diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 5cce8ff2c46fd238dc64c7e852901ea5efacb434..31fac7caab2940f59955e4b3cd659ff06437547e 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -176,7 +176,6 @@ set(llcommon_HEADER_FILES
     llhandle.h
     llhash.h
     llheartbeat.h
-    llhttpstatuscodes.h
     llindexedqueue.h
     llinitparam.h
     llinstancetracker.h
diff --git a/indra/llcommon/llhttpstatuscodes.h b/indra/llcommon/llhttpstatuscodes.h
deleted file mode 100644
index 0173461dad3966ffc81b94225b7ef5d254f1617b..0000000000000000000000000000000000000000
--- a/indra/llcommon/llhttpstatuscodes.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/** 
- * @file llhttpstatuscodes.h
- * @brief Constants for HTTP status codes
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_HTTP_STATUS_CODES_H
-#define LL_HTTP_STATUS_CODES_H
-
-#include "stdtypes.h"
-
-// Standard errors from HTTP spec:
-// http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1
-const S32 HTTP_CONTINUE = 100;
-const S32 HTTP_SWITCHING_PROTOCOLS = 101;
-
-// Success
-const S32 HTTP_OK = 200;
-const S32 HTTP_CREATED = 201;
-const S32 HTTP_ACCEPTED = 202;
-const S32 HTTP_NON_AUTHORITATIVE_INFORMATION = 203;
-const S32 HTTP_NO_CONTENT = 204;
-const S32 HTTP_RESET_CONTENT = 205;
-const S32 HTTP_PARTIAL_CONTENT = 206;
-
-// Redirection
-const S32 HTTP_MULTIPLE_CHOICES = 300;
-const S32 HTTP_MOVED_PERMANENTLY = 301;
-const S32 HTTP_FOUND = 302;
-const S32 HTTP_SEE_OTHER = 303;
-const S32 HTTP_NOT_MODIFIED = 304;
-const S32 HTTP_USE_PROXY = 305;
-const S32 HTTP_TEMPORARY_REDIRECT = 307;
-
-// Client Error
-const S32 HTTP_BAD_REQUEST = 400;
-const S32 HTTP_UNAUTHORIZED = 401;
-const S32 HTTP_PAYMENT_REQUIRED = 402;
-const S32 HTTP_FORBIDDEN = 403;
-const S32 HTTP_NOT_FOUND = 404;
-const S32 HTTP_METHOD_NOT_ALLOWED = 405;
-const S32 HTTP_NOT_ACCEPTABLE = 406;
-const S32 HTTP_PROXY_AUTHENTICATION_REQUIRED = 407;
-const S32 HTTP_REQUEST_TIME_OUT = 408;
-const S32 HTTP_CONFLICT = 409;
-const S32 HTTP_GONE = 410;
-const S32 HTTP_LENGTH_REQUIRED = 411;
-const S32 HTTP_PRECONDITION_FAILED = 412;
-const S32 HTTP_REQUEST_ENTITY_TOO_LARGE = 413;
-const S32 HTTP_REQUEST_URI_TOO_LARGE = 414;
-const S32 HTTP_UNSUPPORTED_MEDIA_TYPE = 415;
-const S32 HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
-const S32 HTTP_EXPECTATION_FAILED = 417;
-
-// Server Error
-const S32 HTTP_INTERNAL_SERVER_ERROR = 500;
-const S32 HTTP_NOT_IMPLEMENTED = 501;
-const S32 HTTP_BAD_GATEWAY = 502;
-const S32 HTTP_SERVICE_UNAVAILABLE = 503;
-const S32 HTTP_GATEWAY_TIME_OUT = 504;
-const S32 HTTP_VERSION_NOT_SUPPORTED = 505;
-
-// We combine internal process errors with status codes
-// These status codes should not be sent over the wire
-//   and indicate something went wrong internally.
-// If you get these they are not normal.
-const S32 HTTP_INTERNAL_ERROR = 499;
-
-#endif
diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp
index 8276ec836a77399ed164ff02d4ec65a3286aafb5..9e4b92227ed807666e26f063ddb4e1a3bb9ba558 100644
--- a/indra/llcommon/llsd.cpp
+++ b/indra/llcommon/llsd.cpp
@@ -126,7 +126,9 @@ class LLSD::Impl
 	virtual UUID	asUUID() const				{ return LLUUID(); }
 	virtual Date	asDate() const				{ return LLDate(); }
 	virtual URI		asURI() const				{ return LLURI(); }
-	virtual Binary	asBinary() const			{ return std::vector<U8>(); }
+	virtual const Binary&	asBinary() const	{ static const std::vector<U8> empty; return empty; }
+
+	virtual const String& asStringRef() const { static const std::string empty; return empty; } 
 	
 	virtual bool has(const String&) const		{ return false; }
 	virtual LLSD get(const String&) const		{ return LLSD(); }
@@ -270,6 +272,7 @@ namespace
 		virtual LLSD::Date		asDate() const	{ return LLDate(mValue); }
 		virtual LLSD::URI		asURI() const	{ return LLURI(mValue); }
 		virtual int				size() const	{ return mValue.size(); }
+		virtual const LLSD::String&	asStringRef() const { return mValue; }
 	};
 	
 	LLSD::Integer	ImplString::asInteger() const
@@ -348,7 +351,7 @@ namespace
 	public:
 		ImplBinary(const LLSD::Binary& v) : Base(v) { }
 				
-		virtual LLSD::Binary	asBinary() const{ return mValue; }
+		virtual const LLSD::Binary&	asBinary() const{ return mValue; }
 	};
 
 
@@ -838,7 +841,9 @@ LLSD::String	LLSD::asString() const	{ return safe(impl).asString(); }
 LLSD::UUID		LLSD::asUUID() const	{ return safe(impl).asUUID(); }
 LLSD::Date		LLSD::asDate() const	{ return safe(impl).asDate(); }
 LLSD::URI		LLSD::asURI() const		{ return safe(impl).asURI(); }
-LLSD::Binary	LLSD::asBinary() const	{ return safe(impl).asBinary(); }
+const LLSD::Binary&	LLSD::asBinary() const	{ return safe(impl).asBinary(); }
+
+const LLSD::String& LLSD::asStringRef() const { return safe(impl).asStringRef(); }
 
 // const char * helpers
 LLSD::LLSD(const char* v) : impl(0)		{ ALLOC_LLSD_OBJECT;	assign(v); }
diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h
index 5eb69059ac6e5f41e4f76504f6d081419652766f..b9f490718c5f4bcdd5472d63009718bc77b7388c 100644
--- a/indra/llcommon/llsd.h
+++ b/indra/llcommon/llsd.h
@@ -249,7 +249,10 @@ class LL_COMMON_API LLSD
 		UUID	asUUID() const;
 		Date	asDate() const;
 		URI		asURI() const;
-		Binary	asBinary() const;
+		const Binary&	asBinary() const;
+
+		// asStringRef on any non-string type will return a ref to an empty string.
+		const String&	asStringRef() const;
 
 		operator Boolean() const	{ return asBoolean(); }
 		operator Integer() const	{ return asInteger(); }
diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index ad4fce6f359b8dbb6277402ed615394c98de118a..774d827762757b86b32fcec5891584b28638a872 100644
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
@@ -873,7 +873,7 @@ S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data) const
 {
 /**
  * Undefined: '!'<br>
- * Boolean: 't' for true 'f' for false<br>
+ * Boolean: '1' for true '0' for false<br>
  * Integer: 'i' + 4 bytes network byte order<br>
  * Real: 'r' + 8 bytes IEEE double<br>
  * UUID: 'u' + 16 byte unsigned integer<br>
@@ -1260,13 +1260,38 @@ std::string LLSDNotationFormatter::escapeString(const std::string& in)
 
 // virtual
 S32 LLSDNotationFormatter::format(const LLSD& data, std::ostream& ostr, U32 options) const
+{
+	S32 rv = format_impl(data, ostr, options, 0);
+	return rv;
+}
+
+S32 LLSDNotationFormatter::format_impl(const LLSD& data, std::ostream& ostr, U32 options, U32 level) const
 {
 	S32 format_count = 1;
+	std::string pre;
+	std::string post;
+
+	if (options & LLSDFormatter::OPTIONS_PRETTY)
+	{
+		for (U32 i = 0; i < level; i++)
+		{
+			pre += "    ";
+		}
+		post = "\n";
+	}
+
 	switch(data.type())
 	{
 	case LLSD::TypeMap:
 	{
+		if (0 != level) ostr << post << pre;
 		ostr << "{";
+		std::string inner_pre;
+		if (options & LLSDFormatter::OPTIONS_PRETTY)
+		{
+			inner_pre = pre + "    ";
+		}
+
 		bool need_comma = false;
 		LLSD::map_const_iterator iter = data.beginMap();
 		LLSD::map_const_iterator end = data.endMap();
@@ -1274,18 +1299,18 @@ S32 LLSDNotationFormatter::format(const LLSD& data, std::ostream& ostr, U32 opti
 		{
 			if(need_comma) ostr << ",";
 			need_comma = true;
-			ostr << '\'';
+			ostr << post << inner_pre << '\'';
 			serialize_string((*iter).first, ostr);
 			ostr << "':";
-			format_count += format((*iter).second, ostr);
+			format_count += format_impl((*iter).second, ostr, options, level + 2);
 		}
-		ostr << "}";
+		ostr << post << pre << "}";
 		break;
 	}
 
 	case LLSD::TypeArray:
 	{
-		ostr << "[";
+		ostr << post << pre << "[";
 		bool need_comma = false;
 		LLSD::array_const_iterator iter = data.beginArray();
 		LLSD::array_const_iterator end = data.endArray();
@@ -1293,7 +1318,7 @@ S32 LLSDNotationFormatter::format(const LLSD& data, std::ostream& ostr, U32 opti
 		{
 			if(need_comma) ostr << ",";
 			need_comma = true;
-			format_count += format(*iter, ostr);
+			format_count += format_impl(*iter, ostr, options, level + 1);
 		}
 		ostr << "]";
 		break;
@@ -1343,7 +1368,7 @@ S32 LLSDNotationFormatter::format(const LLSD& data, std::ostream& ostr, U32 opti
 
 	case LLSD::TypeString:
 		ostr << '\'';
-		serialize_string(data.asString(), ostr);
+		serialize_string(data.asStringRef(), ostr);
 		ostr << '\'';
 		break;
 
@@ -1360,9 +1385,26 @@ S32 LLSDNotationFormatter::format(const LLSD& data, std::ostream& ostr, U32 opti
 	case LLSD::TypeBinary:
 	{
 		// *FIX: memory inefficient.
-		std::vector<U8> buffer = data.asBinary();
+		const std::vector<U8>& buffer = data.asBinary();
 		ostr << "b(" << buffer.size() << ")\"";
-		if(buffer.size()) ostr.write((const char*)&buffer[0], buffer.size());
+		if(buffer.size())
+		{
+			if (options & LLSDFormatter::OPTIONS_PRETTY_BINARY)
+			{
+				std::ios_base::fmtflags old_flags = ostr.flags();
+				ostr.setf( std::ios::hex, std::ios::basefield );
+				ostr << "0x";
+				for (int i = 0; i < buffer.size(); i++)
+				{
+					ostr << (int) buffer[i];
+				}
+				ostr.flags(old_flags);
+			}
+			else
+			{
+				ostr.write((const char*)&buffer[0], buffer.size());
+			}
+		}
 		ostr << "\"";
 		break;
 	}
@@ -1460,7 +1502,7 @@ S32 LLSDBinaryFormatter::format(const LLSD& data, std::ostream& ostr, U32 option
 
 	case LLSD::TypeString:
 		ostr.put('s');
-		formatString(data.asString(), ostr);
+		formatString(data.asStringRef(), ostr);
 		break;
 
 	case LLSD::TypeDate:
@@ -1478,9 +1520,8 @@ S32 LLSDBinaryFormatter::format(const LLSD& data, std::ostream& ostr, U32 option
 
 	case LLSD::TypeBinary:
 	{
-		// *FIX: memory inefficient.
 		ostr.put('b');
-		std::vector<U8> buffer = data.asBinary();
+		const std::vector<U8>& buffer = data.asBinary();
 		U32 size_nbo = htonl(buffer.size());
 		ostr.write((const char*)(&size_nbo), sizeof(U32));
 		if(buffer.size()) ostr.write((const char*)&buffer[0], buffer.size());
diff --git a/indra/llcommon/llsdserialize.h b/indra/llcommon/llsdserialize.h
index e7a5507385c07bd0c05b42d2477336e04d6d3c1d..23a0c8cfb1e332ea0346517c1cec74d2e33514b9 100644
--- a/indra/llcommon/llsdserialize.h
+++ b/indra/llcommon/llsdserialize.h
@@ -416,7 +416,8 @@ class LL_COMMON_API LLSDFormatter : public LLRefCount
 	typedef enum e_formatter_options_type
 	{
 		OPTIONS_NONE = 0,
-		OPTIONS_PRETTY = 1
+		OPTIONS_PRETTY = 1,
+		OPTIONS_PRETTY_BINARY = 2
 	} EFormatterOptions;
 
 	/** 
@@ -507,6 +508,17 @@ class LL_COMMON_API LLSDNotationFormatter : public LLSDFormatter
 	 * @return Returns The number of LLSD objects fomatted out
 	 */
 	virtual S32 format(const LLSD& data, std::ostream& ostr, U32 options = LLSDFormatter::OPTIONS_NONE) const;
+
+protected:
+
+	/** 
+	 * @brief Implementation to format the data. This is called recursively.
+	 *
+	 * @param data The data to write.
+	 * @param ostr The destination stream for the data.
+	 * @return Returns The number of LLSD objects fomatted out
+	 */
+	S32 format_impl(const LLSD& data, std::ostream& ostr, U32 options, U32 level) const;
 };
 
 
@@ -634,7 +646,7 @@ class LL_COMMON_API LLSDBinaryFormatter : public LLSDFormatter
  *  </code>
  *
  * *NOTE - formerly this class inherited from its template parameter Formatter,
- * but all insnatiations passed in LLRefCount subclasses.  This conflicted with
+ * but all instantiations passed in LLRefCount subclasses.  This conflicted with
  * the auto allocation intended for this class template (demonstrated in the
  * example above).  -brad
  */
@@ -720,6 +732,18 @@ class LL_COMMON_API LLSDSerialize
 		LLPointer<LLSDNotationFormatter> f = new LLSDNotationFormatter;
 		return f->format(sd, str, LLSDFormatter::OPTIONS_NONE);
 	}
+	static S32 toPrettyNotation(const LLSD& sd, std::ostream& str)
+	{
+		LLPointer<LLSDNotationFormatter> f = new LLSDNotationFormatter;
+		return f->format(sd, str, LLSDFormatter::OPTIONS_PRETTY);
+	}
+	static S32 toPrettyBinaryNotation(const LLSD& sd, std::ostream& str)
+	{
+		LLPointer<LLSDNotationFormatter> f = new LLSDNotationFormatter;
+		return f->format(sd, str, 
+				LLSDFormatter::OPTIONS_PRETTY | 
+				LLSDFormatter::OPTIONS_PRETTY_BINARY);
+	}
 	static S32 fromNotation(LLSD& sd, std::istream& str, S32 max_bytes)
 	{
 		LLPointer<LLSDNotationParser> p = new LLSDNotationParser;
diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp
index cef743a7beab012a31a2b42233da8f33db9588b6..3ef7a7e4c12b5af547640bb45472e822f8600dce 100644
--- a/indra/llcommon/llsdserialize_xml.cpp
+++ b/indra/llcommon/llsdserialize_xml.cpp
@@ -168,8 +168,8 @@ S32 LLSDXMLFormatter::format_impl(const LLSD& data, std::ostream& ostr, U32 opti
 		break;
 
 	case LLSD::TypeString:
-		if(data.asString().empty()) ostr << pre << "<string />" << post;
-		else ostr << pre << "<string>" << escapeString(data.asString()) <<"</string>" << post;
+		if(data.asStringRef().empty()) ostr << pre << "<string />" << post;
+		else ostr << pre << "<string>" << escapeString(data.asStringRef()) <<"</string>" << post;
 		break;
 
 	case LLSD::TypeDate:
@@ -182,7 +182,7 @@ S32 LLSDXMLFormatter::format_impl(const LLSD& data, std::ostream& ostr, U32 opti
 
 	case LLSD::TypeBinary:
 	{
-		LLSD::Binary buffer = data.asBinary();
+		const LLSD::Binary& buffer = data.asBinary();
 		if(buffer.empty())
 		{
 			ostr << pre << "<binary />" << post;
@@ -375,13 +375,10 @@ S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data)
 		{
 			break;
 		}
+		count = get_till_eol(input, (char *)buffer, BUFFER_SIZE);
+		if (!count)
 		{
-		
-			count = get_till_eol(input, (char *)buffer, BUFFER_SIZE);
-			if (!count)
-			{
-				break;
-			}
+			break;
 		}
 		status = XML_ParseBuffer(mParser, count, false);
 
diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp
index 6fe0bfc7d1a1dcdab3eebfabdd80f83a6a522853..9ea831a771619f6feeaa6026437ab64869113137 100644
--- a/indra/llcorehttp/_httplibcurl.cpp
+++ b/indra/llcorehttp/_httplibcurl.cpp
@@ -31,7 +31,7 @@
 #include "_httpoprequest.h"
 #include "_httppolicy.h"
 
-#include "llhttpstatuscodes.h"
+#include "llhttpconstants.h"
 
 
 namespace LLCore
diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp
index 7db19b18410ccf7d8293580a9c992c31e297f3d2..5e703cd1831c8a63b1ffce7f6c43b53455e023e7 100644
--- a/indra/llcorehttp/_httpoprequest.cpp
+++ b/indra/llcorehttp/_httpoprequest.cpp
@@ -44,7 +44,7 @@
 #include "_httplibcurl.h"
 #include "_httpinternal.h"
 
-#include "llhttpstatuscodes.h"
+#include "llhttpconstants.h"
 #include "llproxy.h"
 
 namespace
@@ -479,6 +479,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
 			curl_easy_setopt(mCurlHandle, CURLOPT_INFILESIZE, data_size);
 			curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDS, (void *) NULL);
 			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");
 		}
diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp
index fb2d43e3b0d6c25af71214e8cf3f1bbe255198fd..b86e73c69070495c0bdee360b76d22e4933ddef3 100644
--- a/indra/llcrashlogger/llcrashlogger.cpp
+++ b/indra/llcrashlogger/llcrashlogger.cpp
@@ -50,18 +50,21 @@ BOOL gSent = false;
 
 class LLCrashLoggerResponder : public LLHTTPClient::Responder
 {
+	LOG_CLASS(LLCrashLoggerResponder);
 public:
 	LLCrashLoggerResponder() 
 	{
 	}
 
-	virtual void error(U32 status, const std::string& reason)
+protected:
+	virtual void httpFailure()
 	{
+		llwarns << dumpResponse() << llendl;
 		gBreak = true;
 	}
 
-	virtual void result(const LLSD& content)
-	{	
+	virtual void httpSuccess()
+	{
 		gBreak = true;
 		gSent = true;
 	}
diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt
index 1a90c32fe4fd0ee38433164a7e7a0d59ddfb885a..181718f46582d3cfcc212df7cc7396b4a0a9888d 100644
--- a/indra/llmessage/CMakeLists.txt
+++ b/indra/llmessage/CMakeLists.txt
@@ -43,6 +43,7 @@ set(llmessage_SOURCE_FILES
     llhttpassetstorage.cpp
     llhttpclient.cpp
     llhttpclientadapter.cpp
+    llhttpconstants.cpp
     llhttpnode.cpp
     llhttpsender.cpp
     llinstantmessage.cpp
@@ -67,7 +68,6 @@ set(llmessage_SOURCE_FILES
     llpartdata.cpp
     llproxy.cpp
     llpumpio.cpp
-    llregionpresenceverifier.cpp
     llsdappservices.cpp
     llsdhttpserver.cpp
     llsdmessage.cpp
@@ -135,6 +135,7 @@ set(llmessage_HEADER_FILES
     llhttpclient.h
     llhttpclientinterface.h
     llhttpclientadapter.h
+    llhttpconstants.h
     llhttpnode.h
     llhttpnodeadapter.h
     llhttpsender.h
@@ -166,7 +167,6 @@ set(llmessage_HEADER_FILES
     llqueryflags.h
     llregionflags.h
     llregionhandle.h
-    llregionpresenceverifier.h
     llsdappservices.h
     llsdhttpserver.h
     llsdmessage.h
@@ -230,17 +230,15 @@ target_link_libraries(
 # tests
 if (LL_TESTS)
   SET(llmessage_TEST_SOURCE_FILES
-    # llhttpclientadapter.cpp
-    llmime.cpp
     llnamevalue.cpp
     lltrustedmessageservice.cpp
     lltemplatemessagedispatcher.cpp
-      llregionpresenceverifier.cpp
     )
   LL_ADD_PROJECT_UNIT_TESTS(llmessage "${llmessage_TEST_SOURCE_FILES}")
 
   #    set(TEST_DEBUG on)
   set(test_libs
+    ${CURL_LIBRARIES}
     ${LLMESSAGE_LIBRARIES}
     ${WINDOWS_LIBRARIES}
     ${LLVFS_LIBRARIES}
@@ -267,6 +265,8 @@ if (LL_TESTS)
 
   LL_ADD_INTEGRATION_TEST(llavatarnamecache "" "${test_libs}")
   LL_ADD_INTEGRATION_TEST(llhost "" "${test_libs}")
+  LL_ADD_INTEGRATION_TEST(llhttpclientadapter "" "${test_libs}")
+  LL_ADD_INTEGRATION_TEST(llmime "" "${test_libs}")
   LL_ADD_INTEGRATION_TEST(llpartdata "" "${test_libs}")
   LL_ADD_INTEGRATION_TEST(llxfer_file "" "${test_libs}")
 endif (LL_TESTS)
diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index f9e3ad26f74d0b064e1c16809bfce861ddb0665c..87c4b5952c499cdeee7071219afb022dd8bc2fa4 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -126,7 +126,7 @@ namespace LLAvatarNameCache
 	// Erase expired names from cache
 	void eraseUnrefreshed();
 
-	bool expirationFromCacheControl(LLSD headers, F64 *expires);
+	bool expirationFromCacheControl(const LLSD& headers, F64 *expires);
 }
 
 /* Sample response:
@@ -170,33 +170,31 @@ namespace LLAvatarNameCache
 
 class LLAvatarNameResponder : public LLHTTPClient::Responder
 {
+	LOG_CLASS(LLAvatarNameResponder);
 private:
 	// need to store agent ids that are part of this request in case of
 	// an error, so we can flag them as unavailable
 	std::vector<LLUUID> mAgentIDs;
 
-	// Need the headers to look up Expires: and Retry-After:
-	LLSD mHeaders;
-	
 public:
 	LLAvatarNameResponder(const std::vector<LLUUID>& agent_ids)
-	:	mAgentIDs(agent_ids),
-		mHeaders()
+	:	mAgentIDs(agent_ids)
 	{ }
 	
-	/*virtual*/ void completedHeader(U32 status, const std::string& reason, 
-		const LLSD& headers)
-	{
-		mHeaders = headers;
-	}
-
-	/*virtual*/ void result(const LLSD& content)
+protected:
+	/*virtual*/ void httpSuccess()
 	{
+		const LLSD& content = getContent();
+		if (!content.isMap())
+		{
+			failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+			return;
+		}
 		// Pull expiration out of headers if available
-		F64 expires = LLAvatarNameCache::nameExpirationFromHeaders(mHeaders);
+		F64 expires = LLAvatarNameCache::nameExpirationFromHeaders(getResponseHeaders());
 		F64 now = LLFrameTimer::getTotalSeconds();
 
-		LLSD agents = content["agents"];
+		const LLSD& agents = content["agents"];
 		LLSD::array_const_iterator it = agents.beginArray();
 		for ( ; it != agents.endArray(); ++it)
 		{
@@ -226,7 +224,7 @@ class LLAvatarNameResponder : public LLHTTPClient::Responder
 		}
 
 		// Same logic as error response case
-		LLSD unresolved_agents = content["bad_ids"];
+		const LLSD& unresolved_agents = content["bad_ids"];
 		S32  num_unresolved = unresolved_agents.size();
 		if (num_unresolved > 0)
 		{
@@ -250,14 +248,13 @@ class LLAvatarNameResponder : public LLHTTPClient::Responder
                                  << LL_ENDL;
     }
 
-	/*virtual*/ void error(U32 status, const std::string& reason)
+	/*virtual*/ void httpFailure()
 	{
 		// If there's an error, it might be caused by PeopleApi,
 		// or when loading textures on startup and using a very slow 
 		// network, this query may time out.
 		// What we should do depends on whether or not we have a cached name
-		LL_WARNS("AvNameCache") << "LLAvatarNameResponder::error " << status << " " << reason
-								<< LL_ENDL;
+		LL_WARNS("AvNameCache") << dumpResponse() << LL_ENDL;
 
 		// Add dummy records for any agent IDs in this request that we do not have cached already
 		std::vector<LLUUID>::const_iterator it = mAgentIDs.begin();
@@ -748,7 +745,7 @@ void LLAvatarNameCache::insert(const LLUUID& agent_id, const LLAvatarName& av_na
 	sCache[agent_id] = av_name;
 }
 
-F64 LLAvatarNameCache::nameExpirationFromHeaders(LLSD headers)
+F64 LLAvatarNameCache::nameExpirationFromHeaders(const LLSD& headers)
 {
 	F64 expires = 0.0;
 	if (expirationFromCacheControl(headers, &expires))
@@ -764,17 +761,25 @@ F64 LLAvatarNameCache::nameExpirationFromHeaders(LLSD headers)
 	}
 }
 
-bool LLAvatarNameCache::expirationFromCacheControl(LLSD headers, F64 *expires)
+bool LLAvatarNameCache::expirationFromCacheControl(const LLSD& headers, F64 *expires)
 {
 	bool fromCacheControl = false;
 	F64 now = LLFrameTimer::getTotalSeconds();
 
 	// Allow the header to override the default
-	LLSD cache_control_header = headers["cache-control"];
-	if (cache_control_header.isDefined())
+	std::string cache_control;
+	if (headers.has(HTTP_HEADER_CACHE_CONTROL))
+	{
+		cache_control = headers[HTTP_HEADER_CACHE_CONTROL].asString();
+	}
+	else if (headers.has(HTTP_HEADER_LOWER_CACHE_CONTROL))
+	{
+		cache_control = headers[HTTP_HEADER_LOWER_CACHE_CONTROL].asString();
+	}
+
+	if (!cache_control.empty())
 	{
 		S32 max_age = 0;
-		std::string cache_control = cache_control_header.asString();
 		if (max_age_from_cache_control(cache_control, &max_age))
 		{
 			*expires = now + (F64)max_age;
diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h
index 79f170f7c8718b6485445f6c308c0dbcfbd9017a..42c76fe058bb36637aebe78e8540e69d5d5950ef 100644
--- a/indra/llmessage/llavatarnamecache.h
+++ b/indra/llmessage/llavatarnamecache.h
@@ -90,7 +90,7 @@ namespace LLAvatarNameCache
 
 	// Compute name expiration time from HTTP Cache-Control header,
 	// or return default value, in seconds from epoch.
-	F64 nameExpirationFromHeaders(LLSD headers);
+	F64 nameExpirationFromHeaders(const LLSD& headers);
 
 	void addUseDisplayNamesCallback(const use_display_name_signal_t::slot_type& cb);
 }
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index 47041a2880710e50e201cca400a3e35f44511b0d..1269b6bc5db429b774c07debe434eef5cb32ff15 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -49,6 +49,7 @@
 #include "llproxy.h"
 #include "llsdserialize.h"
 #include "llstl.h"
+#include "llstring.h"
 #include "llthread.h"
 #include "lltimer.h"
 
@@ -98,7 +99,7 @@ void check_curl_code(CURLcode code)
 	{
 		// linux appears to throw a curl error once per session for a bad initialization
 		// at a pretty random time (when enabling cookies).
-		llinfos << "curl error detected: " << curl_easy_strerror(code) << llendl;
+		LL_WARNS("curl") << "curl error detected: " << curl_easy_strerror(code) << LL_ENDL;
 	}
 }
 
@@ -108,7 +109,7 @@ void check_curl_multi_code(CURLMcode code)
 	{
 		// linux appears to throw a curl error once per session for a bad initialization
 		// at a pretty random time (when enabling cookies).
-		llinfos << "curl multi error detected: " << curl_multi_strerror(code) << llendl;
+		LL_WARNS("curl") << "curl multi error detected: " << curl_multi_strerror(code) << LL_ENDL;
 	}
 }
 
@@ -133,6 +134,7 @@ std::string LLCurl::getVersionString()
 //////////////////////////////////////////////////////////////////////////////
 
 LLCurl::Responder::Responder()
+	: mHTTPMethod(HTTP_INVALID), mStatus(HTTP_INTERNAL_ERROR)
 {
 }
 
@@ -142,22 +144,30 @@ LLCurl::Responder::~Responder()
 }
 
 // virtual
-void LLCurl::Responder::errorWithContent(
-	U32 status,
-	const std::string& reason,
-	const LLSD&)
+void LLCurl::Responder::httpFailure()
 {
-	error(status, reason);
+	LL_WARNS("curl") << dumpResponse() << LL_ENDL;
 }
 
-// virtual
-void LLCurl::Responder::error(U32 status, const std::string& reason)
+std::string LLCurl::Responder::dumpResponse() const 
 {
-	llinfos << mURL << " [" << status << "]: " << reason << llendl;
+	std::ostringstream s;
+	s << "[" << httpMethodAsVerb(mHTTPMethod) << ":" << mURL << "] "
+	  << "[status:" << mStatus << "] "
+	  << "[reason:" << mReason << "] ";
+
+	if (mResponseHeaders.has(HTTP_HEADER_CONTENT_TYPE))
+	{
+		s << "[content-type:" << mResponseHeaders[HTTP_HEADER_CONTENT_TYPE] << "] ";
+	}
+
+	s << "[content:" << mContent << "]";
+
+	return s.str();
 }
 
 // virtual
-void LLCurl::Responder::result(const LLSD& content)
+void LLCurl::Responder::httpSuccess()
 {
 }
 
@@ -166,44 +176,124 @@ void LLCurl::Responder::setURL(const std::string& url)
 	mURL = url;
 }
 
+void LLCurl::Responder::successResult(const LLSD& content)
+{
+	setResult(HTTP_OK, "", content);
+	httpSuccess();
+}
+
+void LLCurl::Responder::failureResult(S32 status, const std::string& reason, const LLSD& content /* = LLSD() */)
+{
+	setResult(status, reason, content);
+	httpFailure();
+}
+
+void LLCurl::Responder::completeResult(S32 status, const std::string& reason, const LLSD& content /* = LLSD() */)
+{
+	setResult(status, reason, content);
+	httpCompleted();
+}
+
+void LLCurl::Responder::setResult(S32 status, const std::string& reason, const LLSD& content /* = LLSD() */)
+{
+	mStatus = status;
+	mReason = reason;
+	mContent = content;
+}
+
+void LLCurl::Responder::setHTTPMethod(EHTTPMethod method)
+{
+	mHTTPMethod = method;
+}
+
+void LLCurl::Responder::setResponseHeader(const std::string& header, const std::string& value)
+{
+	mResponseHeaders[header] = value;
+}
+
+const std::string& LLCurl::Responder::getResponseHeader(const std::string& header, bool check_lower) const
+{
+	if (mResponseHeaders.has(header))
+	{
+		return mResponseHeaders[header].asStringRef();
+	}
+	if (check_lower)
+	{
+		std::string header_lower(header);
+		LLStringUtil::toLower(header_lower);
+		if (mResponseHeaders.has(header_lower))
+		{
+			return mResponseHeaders[header_lower].asStringRef();
+		}
+	}
+	static const std::string empty;
+	return empty;
+}
+
+bool LLCurl::Responder::hasResponseHeader(const std::string& header, bool check_lower) const
+{
+	if (mResponseHeaders.has(header)) return true;
+	if (check_lower)
+	{
+		std::string header_lower(header);
+		LLStringUtil::toLower(header_lower);
+		return mResponseHeaders.has(header_lower);
+	}
+	return false;
+}
+
 // virtual
 void LLCurl::Responder::completedRaw(
-	U32 status,
-	const std::string& reason,
 	const LLChannelDescriptors& channels,
 	const LLIOPipe::buffer_ptr_t& buffer)
 {
-	LLSD content;
 	LLBufferStream istr(channels, buffer.get());
-	const bool emit_errors = false;
-	if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXML(content, istr, emit_errors))
+	const bool emit_parse_errors = false;
+
+	std::string debug_body("(empty)");
+	bool parsed=true;
+	if (EOF == istr.peek())
+	{
+		parsed=false;
+	}
+	// Try to parse body as llsd, no matter what 'Content-Type' says.
+	else if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXML(mContent, istr, emit_parse_errors))
+	{
+		parsed=false;
+		char body[1025]; 
+		body[1024] = '\0';
+		istr.seekg(0, std::ios::beg);
+		istr.get(body,1024);
+		if (strlen(body) > 0)
+		{
+			mContent = body;
+			debug_body = body;
+		}
+	}
+
+	// Only emit an warning if we failed to parse when 'Content-Type' == 'application/llsd+xml'
+	if (!parsed && (HTTP_CONTENT_LLSD_XML == getResponseHeader(HTTP_HEADER_CONTENT_TYPE)))
 	{
-		llinfos << "Failed to deserialize LLSD. " << mURL << " [" << status << "]: " << reason << llendl;
-		content["reason"] = reason;
+		llwarns << "Failed to deserialize . " << mURL << " [status:" << mStatus << "] " 
+			<< "(" << mReason << ") body: " << debug_body << llendl;
 	}
 
-	completed(status, reason, content);
+	httpCompleted();
 }
 
 // virtual
-void LLCurl::Responder::completed(U32 status, const std::string& reason, const LLSD& content)
+void LLCurl::Responder::httpCompleted()
 {
-	if (isGoodStatus(status))
+	if (isGoodStatus())
 	{
-		result(content);
+		httpSuccess();
 	}
 	else
 	{
-		errorWithContent(status, reason, content);
+		httpFailure();
 	}
 }
 
-//virtual
-void LLCurl::Responder::completedHeader(U32 status, const std::string& reason, const LLSD& content)
-{
-
-}
-
 //////////////////////////////////////////////////////////////////////////////
 
 std::set<CURL*> LLCurl::Easy::sFreeHandles;
@@ -287,7 +377,8 @@ LLCurl::Easy* LLCurl::Easy::getEasy()
 	if (!easy->mCurlEasyHandle)
 	{
 		// this can happen if we have too many open files (fails in c-ares/ares_init.c)
-		llwarns << "allocEasyHandle() returned NULL! Easy handles: " << gCurlEasyCount << " Multi handles: " << gCurlMultiCount << llendl;
+		LL_WARNS("curl") << "allocEasyHandle() returned NULL! Easy handles: " 
+			<< gCurlEasyCount << " Multi handles: " << gCurlMultiCount << LL_ENDL;
 		delete easy;
 		return NULL;
 	}
@@ -312,10 +403,14 @@ LLCurl::Easy::~Easy()
 	for_each(mStrings.begin(), mStrings.end(), DeletePointerArray());
 	LL_CHECK_MEMORY
 	if (mResponder && LLCurl::sNotQuitting) //aborted
-	{	
-		std::string reason("Request timeout, aborted.") ;
-		mResponder->completedRaw(408, //HTTP_REQUEST_TIME_OUT, timeout, abort
-			reason, mChannels, mOutput);		
+	{
+		// HTTP_REQUEST_TIME_OUT, timeout, abort
+		// *TODO: This looks like improper use of the 408 status code.
+		// See: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.9
+		// This status code should be returned by the *server* when:
+		// "The client did not produce a request within the time that the server was prepared to wait."
+		mResponder->setResult(HTTP_REQUEST_TIME_OUT, "Request timeout, aborted.");
+		mResponder->completedRaw(mChannels, mOutput);
 		LL_CHECK_MEMORY
 	}
 	mResponder = NULL;
@@ -379,9 +474,9 @@ void LLCurl::Easy::getTransferInfo(LLCurl::TransferInfo* info)
 	check_curl_code(curl_easy_getinfo(mCurlEasyHandle, CURLINFO_SPEED_DOWNLOAD, &info->mSpeedDownload));
 }
 
-U32 LLCurl::Easy::report(CURLcode code)
+S32 LLCurl::Easy::report(CURLcode code)
 {
-	U32 responseCode = 0;	
+	S32 responseCode = 0;
 	std::string responseReason;
 	
 	if (code == CURLE_OK)
@@ -391,14 +486,15 @@ U32 LLCurl::Easy::report(CURLcode code)
 	}
 	else
 	{
-		responseCode = 499;
+		responseCode = HTTP_INTERNAL_ERROR;
 		responseReason = strerror(code) + " : " + mErrorBuffer;
 		setopt(CURLOPT_FRESH_CONNECT, TRUE);
 	}
 
 	if (mResponder)
 	{	
-		mResponder->completedRaw(responseCode, responseReason, mChannels, mOutput);
+		mResponder->setResult(responseCode, responseReason);
+		mResponder->completedRaw(mChannels, mOutput);
 		mResponder = NULL;
 	}
 	
@@ -435,9 +531,31 @@ void LLCurl::Easy::setoptString(CURLoption option, const std::string& value)
 	check_curl_code(result);
 }
 
+void LLCurl::Easy::slist_append(const std::string& header, const std::string& value)
+{
+	std::string pair(header);
+	if (value.empty())
+	{
+		pair += ":";
+	}
+	else
+	{
+		pair += ": ";
+		pair += value;
+	}
+	slist_append(pair.c_str());
+}
+
 void LLCurl::Easy::slist_append(const char* str)
 {
-	mHeaders = curl_slist_append(mHeaders, str);
+	if (str)
+	{
+		mHeaders = curl_slist_append(mHeaders, str);
+		if (!mHeaders)
+		{
+			llwarns << "curl_slist_append() call returned NULL appending " << str << llendl;
+		}
+	}
 }
 
 size_t curlReadCallback(char* data, size_t size, size_t nmemb, void* user_data)
@@ -524,8 +642,9 @@ void LLCurl::Easy::prepRequest(const std::string& url,
 
 	if (!post)
 	{
-		slist_append("Connection: keep-alive");
-		slist_append("Keep-alive: 300");
+		// *TODO: Should this be set to 'Keep-Alive' ?
+		slist_append(HTTP_HEADER_CONNECTION, "keep-alive");
+		slist_append(HTTP_HEADER_KEEP_ALIVE, "300");
 		// Accept and other headers
 		for (std::vector<std::string>::const_iterator iter = headers.begin();
 			 iter != headers.end(); ++iter)
@@ -804,7 +923,7 @@ S32 LLCurl::Multi::process()
 		++processed;
 		if (msg->msg == CURLMSG_DONE)
 		{
-			U32 response = 0;
+			S32 response = 0;
 			Easy* easy = NULL ;
 
 			{
@@ -823,7 +942,7 @@ S32 LLCurl::Multi::process()
 			}
 			else
 			{
-				response = 499;
+				response = HTTP_INTERNAL_ERROR;
 				//*TODO: change to llwarns
 				llerrs << "cleaned up curl request completed!" << llendl;
 			}
@@ -1122,13 +1241,13 @@ bool LLCurlRequest::getByteRange(const std::string& url,
 	easy->setopt(CURLOPT_HTTPGET, 1);
 	if (length > 0)
 	{
-		std::string range = llformat("Range: bytes=%d-%d", offset,offset+length-1);
-		easy->slist_append(range.c_str());
+		std::string range = llformat("bytes=%d-%d", offset,offset+length-1);
+		easy->slist_append(HTTP_HEADER_RANGE, range);
 	}
 	else if (offset > 0)
 	{
-		std::string range = llformat("Range: bytes=%d-", offset);
-		easy->slist_append(range.c_str());
+		std::string range = llformat("bytes=%d-", offset);
+		easy->slist_append(HTTP_HEADER_RANGE, range);
 	}
 	easy->setHeaders();
 	bool res = addEasy(easy);
@@ -1155,7 +1274,7 @@ bool LLCurlRequest::post(const std::string& url,
 	easy->setopt(CURLOPT_POSTFIELDS, (void*)NULL);
 	easy->setopt(CURLOPT_POSTFIELDSIZE, bytes);
 
-	easy->slist_append("Content-Type: application/llsd+xml");
+	easy->slist_append(HTTP_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML);
 	easy->setHeaders();
 
 	lldebugs << "POSTING: " << bytes << " bytes." << llendl;
@@ -1183,7 +1302,7 @@ bool LLCurlRequest::post(const std::string& url,
 	easy->setopt(CURLOPT_POSTFIELDS, (void*)NULL);
 	easy->setopt(CURLOPT_POSTFIELDSIZE, bytes);
 
-	easy->slist_append("Content-Type: application/octet-stream");
+	easy->slist_append(HTTP_HEADER_CONTENT_TYPE, HTTP_CONTENT_OCTET_STREAM);
 	easy->setHeaders();
 
 	lldebugs << "POSTING: " << bytes << " bytes." << llendl;
@@ -1555,6 +1674,14 @@ void LLCurlEasyRequest::setSSLCtxCallback(curl_ssl_ctx_callback callback, void*
 	}
 }
 
+void LLCurlEasyRequest::slist_append(const std::string& header, const std::string& value)
+{
+	if (isValid() && mEasy)
+	{
+		mEasy->slist_append(header, value);
+	}
+}
+
 void LLCurlEasyRequest::slist_append(const char* str)
 {
 	if (isValid() && mEasy)
diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h
index 7bcf61e233d6ff8967cc3b46c618cdf9d60a5cf6..c72e1e493af2f82b151712444c44fd38e14f68c7 100644
--- a/indra/llmessage/llcurl.h
+++ b/indra/llmessage/llcurl.h
@@ -39,6 +39,7 @@
 #include <curl/curl.h> // TODO: remove dependency
 
 #include "llbuffer.h"
+#include "llhttpconstants.h"
 #include "lliopipe.h"
 #include "llsd.h"
 #include "llthread.h"
@@ -77,59 +78,92 @@ class LLCurl
 		Responder();
 		virtual ~Responder();
 
-		/**
-		 * @brief return true if the status code indicates success.
-		 */
-		static bool isGoodStatus(U32 status)
+		virtual bool followRedir() 
 		{
-			return((200 <= status) && (status < 300));
+			return false;
 		}
-		
-		virtual void errorWithContent(
-			U32 status,
-			const std::string& reason,
-			const LLSD& content);
-			//< called by completed() on bad status 
-
-		virtual void error(U32 status, const std::string& reason);
-			//< called by default error(status, reason, content)
-		
-		virtual void result(const LLSD& content);
-			//< called by completed for good status codes.
 
+		/**
+		 * @brief return true if the status code indicates success.
+		 */
+		bool isGoodStatus() const { return isHttpGoodStatus(mStatus); }
+
+		S32 getStatus() const { return mStatus; }
+		const std::string& getReason() const { return mReason; }
+		const LLSD& getContent() const { return mContent; }
+		bool hasResponseHeader(const std::string& header, bool check_lower=false) const;
+		const std::string& getResponseHeader(const std::string& header, bool check_lower=true) const;
+		const LLSD& getResponseHeaders() const { return mResponseHeaders; }
+		const std::string& getURL() const { return mURL; }
+		EHTTPMethod getHTTPMethod() const { return mHTTPMethod; }
+
+		// This formats response information for use in log spam.  Includes content spam.
+		std::string dumpResponse() const;
+
+		// Allows direct triggering of success/error with different results.
+		void completeResult(S32 status, const std::string& reason, const LLSD& content = LLSD());
+		void successResult(const LLSD& content);
+		void failureResult(S32 status, const std::string& reason, const LLSD& content = LLSD());
+
+		// The default implementation will try to parse body content as an LLSD, however
+		// it should not spam about parsing failures unless the server sent a
+		// Content-Type: application/llsd+xml header.
 		virtual void completedRaw(
-			U32 status,
-			const std::string& reason,
 			const LLChannelDescriptors& channels,
 			const LLIOPipe::buffer_ptr_t& buffer);
 			/**< Override point for clients that may want to use this
 			   class when the response is some other format besides LLSD
 			*/
+			
 
-		virtual void completed(
-			U32 status,
-			const std::string& reason,
-			const LLSD& content);
-			/**< The default implemetnation calls
+		// The http* methods are not public since these should be triggered internally
+		// after status, reason, content, etc have been set.
+		// If you need to trigger a completion method, use the *Result methods, above.
+	protected:
+		// These methods are the preferred way to process final results.
+		// By default, when one of these is called the following information will be resolved:
+		// * HTTP status code - getStatus()
+		// * Reason string - getReason()
+		// * Content - getContent()
+		// * Response Headers - getResponseHeaders()
+
+		// By default, httpSuccess is triggered whenever httpCompleted is called with a 2xx status code.
+		virtual void httpSuccess();
+			//< called by completed for good status codes.
+
+		// By default, httpFailure is triggered whenever httpCompleted is called with a non-2xx status code.
+		virtual void httpFailure();
+			//< called by httpCompleted() on bad status 
+
+		// httpCompleted does not generally need to be overridden, unless
+		// you don't care about the status code (which determine httpFailure or httpSuccess)
+		// or if you want to re-interpret what a 'good' vs' bad' status code is.
+		virtual void httpCompleted();
+			/**< The default implementation calls
 				either:
-				* result(), or
-				* error() 
+				* httpSuccess(), or
+				* httpFailure() 
 			*/
-			
-			// Override to handle parsing of the header only.  Note: this is the only place where the contents
-			// of the header can be parsed.  In the ::completed call above only the body is contained in the LLSD.
-			virtual void completedHeader(U32 status, const std::string& reason, const LLSD& content);
-
-			// Used internally to set the url for debugging later.
-			void setURL(const std::string& url);
 
-			virtual bool followRedir() 
-			{
-				return false;
-			}
+	public:
+		void setHTTPMethod(EHTTPMethod method);
+		void setURL(const std::string& url);
+		void setResult(S32 status, const std::string& reason, const LLSD& content = LLSD());
+		void setResponseHeader(const std::string& header, const std::string& value);
 
 	private:
+		// These can be accessed by the get* methods.  Treated as 'read-only' during completion handlers.
+		EHTTPMethod mHTTPMethod;
 		std::string mURL;
+		LLSD mResponseHeaders;
+
+	protected:
+		// These should also generally be treated as 'read-only' during completion handlers
+		// and should be accessed by the get* methods.  The exception to this rule would
+		// be when overriding the completedRaw method in preparation for calling httpCompleted().
+		S32 mStatus;
+		std::string mReason;
+		LLSD mContent;
 	};
 	typedef LLPointer<Responder>	ResponderPtr;
 
@@ -225,10 +259,11 @@ class LLCurl::Easy
 	// Copies the string so that it is guaranteed to stick around
 	void setoptString(CURLoption option, const std::string& value);
 
+	void slist_append(const std::string& header, const std::string& value);
 	void slist_append(const char* str);
 	void setHeaders();
 
-	U32 report(CURLcode);
+	S32 report(CURLcode);
 	void getTransferInfo(LLCurl::TransferInfo* info);
 
 	void prepRequest(const std::string& url, const std::vector<std::string>& headers, LLCurl::ResponderPtr, S32 time_out = 0, bool post = false);
@@ -484,6 +519,7 @@ class LLCurlEasyRequest
 	void setWriteCallback(curl_write_callback callback, void* userdata);
 	void setReadCallback(curl_read_callback callback, void* userdata);
 	void setSSLCtxCallback(curl_ssl_ctx_callback callback, void* userdata);
+	void slist_append(const std::string& header, const std::string& value);
 	void slist_append(const char* str);
 	void sendRequest(const std::string& url);
 	void requestComplete();
diff --git a/indra/llmessage/llhttpassetstorage.cpp b/indra/llmessage/llhttpassetstorage.cpp
index 7dcf160c9ba9c3ccb8d88a4b84d09cdbbac7d01f..e841c8e3ed548177739ce57ee875357e6927b1af 100644
--- a/indra/llmessage/llhttpassetstorage.cpp
+++ b/indra/llmessage/llhttpassetstorage.cpp
@@ -51,13 +51,6 @@ const F32 GET_URL_TO_FILE_TIMEOUT = 1800.0f;
 
 const S32 COMPRESSED_INPUT_BUFFER_SIZE = 4096;
 
-const S32 HTTP_OK = 200;
-const S32 HTTP_PUT_OK = 201;
-const S32 HTTP_NO_CONTENT = 204;
-const S32 HTTP_MISSING = 404;
-const S32 HTTP_SERVER_BAD_GATEWAY = 502;
-const S32 HTTP_SERVER_TEMP_UNAVAILABLE = 503;
-
 /////////////////////////////////////////////////////////////////////////////////
 // LLTempAssetData
 // An asset not stored on central asset store, but on a simulator node somewhere.
@@ -952,7 +945,7 @@ void LLHTTPAssetStorage::checkForTimeouts()
 			{
 				if (curl_msg->data.result == CURLE_OK && 
 					(   curl_result == HTTP_OK 
-					 || curl_result == HTTP_PUT_OK 
+					 || curl_result == HTTP_CREATED
 					 || curl_result == HTTP_NO_CONTENT))
 				{
 					llinfos << "Success uploading " << req->getUUID() << " to " << req->mURLBuffer << llendl;
@@ -963,8 +956,8 @@ void LLHTTPAssetStorage::checkForTimeouts()
 				}
 				else if (curl_msg->data.result == CURLE_COULDNT_CONNECT ||
 						curl_msg->data.result == CURLE_OPERATION_TIMEOUTED ||
-						curl_result == HTTP_SERVER_BAD_GATEWAY ||
-						curl_result == HTTP_SERVER_TEMP_UNAVAILABLE)
+						curl_result == HTTP_BAD_GATEWAY ||
+						curl_result == HTTP_SERVICE_UNAVAILABLE)
 				{
 					llwarns << "Re-requesting upload for " << req->getUUID() << ".  Received upload error to " << req->mURLBuffer <<
 						" with result " << curl_easy_strerror(curl_msg->data.result) << ", http result " << curl_result << llendl;
@@ -985,8 +978,8 @@ void LLHTTPAssetStorage::checkForTimeouts()
 
 				if (!(curl_msg->data.result == CURLE_COULDNT_CONNECT ||
 						curl_msg->data.result == CURLE_OPERATION_TIMEOUTED ||
-						curl_result == HTTP_SERVER_BAD_GATEWAY ||
-						curl_result == HTTP_SERVER_TEMP_UNAVAILABLE))
+						curl_result == HTTP_BAD_GATEWAY ||
+						curl_result == HTTP_SERVICE_UNAVAILABLE))
 				{
 					// shared upload finished callback
 					// in the base class, this is called from processUploadComplete
@@ -1018,7 +1011,7 @@ void LLHTTPAssetStorage::checkForTimeouts()
 					llwarns << "Failure downloading " << req->mURLBuffer << 
 						" with result " << curl_easy_strerror(curl_msg->data.result) << ", http result " << curl_result << llendl;
 
-					xfer_result = (curl_result == HTTP_MISSING) ? LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE : LL_ERR_ASSET_REQUEST_FAILED;
+					xfer_result = (curl_result == HTTP_NOT_FOUND) ? LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE : LL_ERR_ASSET_REQUEST_FAILED;
 
 					if (req->mVFile)
 					{
@@ -1240,7 +1233,7 @@ S32 LLHTTPAssetStorage::getURLToFile(const LLUUID& uuid, LLAssetType::EType asse
 		}
 		else
 		{
-			xfer_result = curl_result == HTTP_MISSING ? LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE : LL_ERR_ASSET_REQUEST_FAILED;
+			xfer_result = curl_result == HTTP_NOT_FOUND ? LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE : LL_ERR_ASSET_REQUEST_FAILED;
 			llinfos << "Failure downloading " << req.mURLBuffer << 
 				" with result " << curl_easy_strerror(curl_msg->data.result) << ", http result " << curl_result << llendl;
 		}
diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp
index 0c325a68aaed740a04a71019a4163b86b64ad999..a4a1f02cd3c93ab720bc23b3f7efcdd10f0a1bc0 100644
--- a/indra/llmessage/llhttpclient.cpp
+++ b/indra/llmessage/llhttpclient.cpp
@@ -54,7 +54,7 @@ namespace
 	{
 	public:
 		LLHTTPClientURLAdaptor(LLCurl::ResponderPtr responder)
-			: LLURLRequestComplete(), mResponder(responder), mStatus(499),
+			: LLURLRequestComplete(), mResponder(responder), mStatus(HTTP_INTERNAL_ERROR),
 			  mReason("LLURLRequest complete w/no status")
 		{
 		}
@@ -63,7 +63,7 @@ namespace
 		{
 		}
 
-		virtual void httpStatus(U32 status, const std::string& reason)
+		virtual void httpStatus(S32 status, const std::string& reason)
 		{
 			LLURLRequestComplete::httpStatus(status,reason);
 
@@ -74,30 +74,33 @@ namespace
 		virtual void complete(const LLChannelDescriptors& channels,
 							  const buffer_ptr_t& buffer)
 		{
+			// *TODO: Re-interpret mRequestStatus codes?
+			//        Would like to detect curl errors, such as
+			//        connection errors, write erros, etc.
 			if (mResponder.get())
 			{
-				// Allow clients to parse headers before we attempt to parse
-				// the body and provide completed/result/error calls.
-				mResponder->completedHeader(mStatus, mReason, mHeaderOutput);
-				mResponder->completedRaw(mStatus, mReason, channels, buffer);
+				mResponder->setResult(mStatus, mReason);
+				mResponder->completedRaw(channels, buffer);
 			}
 		}
 		virtual void header(const std::string& header, const std::string& value)
 		{
-			mHeaderOutput[header] = value;
+			if (mResponder.get())
+			{
+				mResponder->setResponseHeader(header, value);
+			}
 		}
 
 	private:
 		LLCurl::ResponderPtr mResponder;
-		U32 mStatus;
+		S32 mStatus;
 		std::string mReason;
-		LLSD mHeaderOutput;
 	};
 	
 	class Injector : public LLIOPipe
 	{
 	public:
-		virtual const char* contentType() = 0;
+		virtual const std::string& contentType() = 0;
 	};
 
 	class LLSDInjector : public Injector
@@ -106,7 +109,7 @@ namespace
 		LLSDInjector(const LLSD& sd) : mSD(sd) {}
 		virtual ~LLSDInjector() {}
 
-		const char* contentType() { return "application/llsd+xml"; }
+		const std::string& contentType() { return HTTP_CONTENT_LLSD_XML; }
 
 		virtual EStatus process_impl(const LLChannelDescriptors& channels,
 			buffer_ptr_t& buffer, bool& eos, LLSD& context, LLPumpIO* pump)
@@ -126,7 +129,7 @@ namespace
 		RawInjector(const U8* data, S32 size) : mData(data), mSize(size) {}
 		virtual ~RawInjector() {delete mData;}
 
-		const char* contentType() { return "application/octet-stream"; }
+		const std::string& contentType() { return HTTP_CONTENT_OCTET_STREAM; }
 
 		virtual EStatus process_impl(const LLChannelDescriptors& channels,
 			buffer_ptr_t& buffer, bool& eos, LLSD& context, LLPumpIO* pump)
@@ -147,7 +150,7 @@ namespace
 		FileInjector(const std::string& filename) : mFilename(filename) {}
 		virtual ~FileInjector() {}
 
-		const char* contentType() { return "application/octet-stream"; }
+		const std::string& contentType() { return HTTP_CONTENT_OCTET_STREAM; }
 
 		virtual EStatus process_impl(const LLChannelDescriptors& channels,
 			buffer_ptr_t& buffer, bool& eos, LLSD& context, LLPumpIO* pump)
@@ -180,7 +183,7 @@ namespace
 		VFileInjector(const LLUUID& uuid, LLAssetType::EType asset_type) : mUUID(uuid), mAssetType(asset_type) {}
 		virtual ~VFileInjector() {}
 
-		const char* contentType() { return "application/octet-stream"; }
+		const std::string& contentType() { return HTTP_CONTENT_OCTET_STREAM; }
 
 		virtual EStatus process_impl(const LLChannelDescriptors& channels,
 			buffer_ptr_t& buffer, bool& eos, LLSD& context, LLPumpIO* pump)
@@ -213,7 +216,7 @@ void LLHTTPClient::setCertVerifyCallback(LLURLRequest::SSLCertVerifyCallback cal
 
 static void request(
 	const std::string& url,
-	LLURLRequest::ERequestAction method,
+	EHTTPMethod method,
 	Injector* body_injector,
 	LLCurl::ResponderPtr responder,
 	const F32 timeout = HTTP_REQUEST_EXPIRY_SECS,
@@ -222,7 +225,11 @@ static void request(
 {
 	if (!LLHTTPClient::hasPump())
 	{
-		responder->completed(U32_MAX, "No pump", LLSD());
+		if (responder)
+		{
+			responder->completeResult(HTTP_INTERNAL_ERROR, "No pump");
+		}
+		delete body_injector;
 		return;
 	}
 	LLPumpIO::chain_t chain;
@@ -230,20 +237,24 @@ static void request(
 	LLURLRequest* req = new LLURLRequest(method, url);
 	if(!req->isValid())//failed
 	{
-		delete req ;
-		return ;
+		if (responder)
+		{
+			responder->completeResult(HTTP_INTERNAL_CURL_ERROR, "Internal Error - curl failure");
+		}
+		delete req;
+		delete body_injector;
+		return;
 	}
 
 	req->setSSLVerifyCallback(LLHTTPClient::getCertVerifyCallback(), (void *)req);
 
 	
-	lldebugs << LLURLRequest::actionAsVerb(method) << " " << url << " "
-		<< headers << llendl;
+	LL_DEBUGS("LLHTTPClient") << httpMethodAsVerb(method) << " " << url << " " << headers << LL_ENDL;
 
 	// Insert custom headers if the caller sent any
 	if (headers.isMap())
 	{
-		if (headers.has("Cookie"))
+		if (headers.has(HTTP_HEADER_COOKIE))
 		{
 			req->allowCookies();
 		}
@@ -253,62 +264,56 @@ static void request(
 
         for (; iter != end; ++iter)
         {
-            std::ostringstream header;
             //if the header is "Pragma" with no value
             //the caller intends to force libcurl to drop
             //the Pragma header it so gratuitously inserts
             //Before inserting the header, force libcurl
             //to not use the proxy (read: llurlrequest.cpp)
-			static const std::string PRAGMA("Pragma");
-			if ((iter->first == PRAGMA) && (iter->second.asString().empty()))
+			if ((iter->first == HTTP_HEADER_PRAGMA) && (iter->second.asString().empty()))
             {
                 req->useProxy(false);
             }
-            header << iter->first << ": " << iter->second.asString() ;
-            lldebugs << "header = " << header.str() << llendl;
-            req->addHeader(header.str().c_str());
+            LL_DEBUGS("LLHTTPClient") << "header = " << iter->first 
+                << ": " << iter->second.asString() << LL_ENDL;
+            req->addHeader(iter->first, iter->second.asString());
         }
     }
 
 	// Check to see if we have already set Accept or not. If no one
 	// set it, set it to application/llsd+xml since that's what we
 	// almost always want.
-	if( method != LLURLRequest::HTTP_PUT && method != LLURLRequest::HTTP_POST )
+	if( method != HTTP_PUT && method != HTTP_POST )
 	{
-		static const std::string ACCEPT("Accept");
-		if(!headers.has(ACCEPT))
+		if(!headers.has(HTTP_HEADER_ACCEPT))
 		{
-			req->addHeader("Accept: application/llsd+xml");
+			req->addHeader(HTTP_HEADER_ACCEPT, HTTP_CONTENT_LLSD_XML);
 		}
 	}
 
 	if (responder)
 	{
 		responder->setURL(url);
+		responder->setHTTPMethod(method);
 	}
 
 	req->setCallback(new LLHTTPClientURLAdaptor(responder));
 
-	if (method == LLURLRequest::HTTP_POST  &&  gMessageSystem)
+	if (method == HTTP_POST  &&  gMessageSystem)
 	{
-		req->addHeader(llformat("X-SecondLife-UDP-Listen-Port: %d",
-								gMessageSystem->mPort).c_str());
+		req->addHeader("X-SecondLife-UDP-Listen-Port", llformat("%d",
+								gMessageSystem->mPort));
    	}
 
-	if (method == LLURLRequest::HTTP_PUT || method == LLURLRequest::HTTP_POST)
+	if (method == HTTP_PUT || method == HTTP_POST)
 	{
-		static const std::string CONTENT_TYPE("Content-Type");
-		if(!headers.has(CONTENT_TYPE))
+		if(!headers.has(HTTP_HEADER_CONTENT_TYPE))
 		{
 			// If the Content-Type header was passed in, it has
 			// already been added as a header through req->addHeader
 			// in the loop above. We defer to the caller's wisdom, but
 			// if they did not specify a Content-Type, then ask the
 			// injector.
-			req->addHeader(
-				llformat(
-					"Content-Type: %s",
-					body_injector->contentType()).c_str());
+			req->addHeader(HTTP_HEADER_CONTENT_TYPE, body_injector->contentType());
 		}
    		chain.push_back(LLIOPipe::ptr_t(body_injector));
 	}
@@ -331,9 +336,9 @@ void LLHTTPClient::getByteRange(
 	if(offset > 0 || bytes > 0)
 	{
 		std::string range = llformat("bytes=%d-%d", offset, offset+bytes-1);
-		headers["Range"] = range;
+		headers[HTTP_HEADER_RANGE] = range;
 	}
-    request(url,LLURLRequest::HTTP_GET, NULL, responder, timeout, headers);
+    request(url,HTTP_GET, NULL, responder, timeout, headers);
 }
 
 void LLHTTPClient::head(
@@ -342,16 +347,16 @@ void LLHTTPClient::head(
 	const LLSD& headers,
 	const F32 timeout)
 {
-	request(url, LLURLRequest::HTTP_HEAD, NULL, responder, timeout, headers);
+	request(url, HTTP_HEAD, NULL, responder, timeout, headers);
 }
 
 void LLHTTPClient::get(const std::string& url, ResponderPtr responder, const LLSD& headers, const F32 timeout)
 {
-	request(url, LLURLRequest::HTTP_GET, NULL, responder, timeout, headers);
+	request(url, HTTP_GET, NULL, responder, timeout, headers);
 }
 void LLHTTPClient::getHeaderOnly(const std::string& url, ResponderPtr responder, const LLSD& headers, const F32 timeout)
 {
-	request(url, LLURLRequest::HTTP_HEAD, NULL, responder, timeout, headers);
+	request(url, HTTP_HEAD, NULL, responder, timeout, headers);
 }
 void LLHTTPClient::getHeaderOnly(const std::string& url, ResponderPtr responder, const F32 timeout)
 {
@@ -392,7 +397,7 @@ class LLHTTPBuffer
 		return content;
 	}
 
-	std::string asString()
+	const std::string& asString()
 	{
 		return mBuffer;
 	}
@@ -421,7 +426,7 @@ class LLHTTPBuffer
   */
 static LLSD blocking_request(
 	const std::string& url,
-	LLURLRequest::ERequestAction method,
+	EHTTPMethod method,
 	const LLSD& body,
 	const LLSD& headers = LLSD(),
 	const F32 timeout = 5
@@ -464,11 +469,11 @@ static LLSD blocking_request(
 	}
 	
 	// * Setup specific method / "verb" for the URI (currently only GET and POST supported + poppy)
-	if (method == LLURLRequest::HTTP_GET)
+	if (method == HTTP_GET)
 	{
 		curl_easy_setopt(curlp, CURLOPT_HTTPGET, 1);
 	}
-	else if (method == LLURLRequest::HTTP_POST)
+	else if (method == HTTP_POST)
 	{
 		curl_easy_setopt(curlp, CURLOPT_POST, 1);
 		//serialize to ostr then copy to str - need to because ostr ptr is unstable :(
@@ -477,18 +482,20 @@ static LLSD blocking_request(
 		body_str = ostr.str();
 		curl_easy_setopt(curlp, CURLOPT_POSTFIELDS, body_str.c_str());
 		//copied from PHP libs, correct?
-		headers_list = curl_slist_append(headers_list, "Content-Type: application/llsd+xml");
+		headers_list = curl_slist_append(headers_list, 
+				llformat("%s: %s", HTTP_HEADER_CONTENT_TYPE.c_str(), HTTP_CONTENT_LLSD_XML.c_str()).c_str());
 
 		// copied from llurlrequest.cpp
 		// it appears that apache2.2.3 or django in etch is busted. If
 		// we do not clear the expect header, we get a 500. May be
 		// limited to django/mod_wsgi.
-		headers_list = curl_slist_append(headers_list, "Expect:");
+		headers_list = curl_slist_append(headers_list, llformat("%s:", HTTP_HEADER_EXPECT.c_str()).c_str());
 	}
 	
 	// * Do the action using curl, handle results
 	lldebugs << "HTTP body: " << body_str << llendl;
-	headers_list = curl_slist_append(headers_list, "Accept: application/llsd+xml");
+	headers_list = curl_slist_append(headers_list,
+				llformat("%s: %s", HTTP_HEADER_ACCEPT.c_str(), HTTP_CONTENT_LLSD_XML.c_str()).c_str());
 	CURLcode curl_result = curl_easy_setopt(curlp, CURLOPT_HTTPHEADER, headers_list);
 	if ( curl_result != CURLE_OK )
 	{
@@ -497,11 +504,11 @@ static LLSD blocking_request(
 
 	LLSD response = LLSD::emptyMap();
 	S32 curl_success = curl_easy_perform(curlp);
-	S32 http_status = 499;
+	S32 http_status = HTTP_INTERNAL_ERROR;
 	curl_easy_getinfo(curlp, CURLINFO_RESPONSE_CODE, &http_status);
 	response["status"] = http_status;
 	// if we get a non-404 and it's not a 200 OR maybe it is but you have error bits,
-	if ( http_status != 404 && (http_status != 200 || curl_success != 0) )
+	if ( http_status != HTTP_NOT_FOUND && (http_status != HTTP_OK || curl_success != 0) )
 	{
 		// We expect 404s, don't spam for them.
 		llwarns << "CURL REQ URL: " << url << llendl;
@@ -531,12 +538,12 @@ static LLSD blocking_request(
 
 LLSD LLHTTPClient::blockingGet(const std::string& url)
 {
-	return blocking_request(url, LLURLRequest::HTTP_GET, LLSD());
+	return blocking_request(url, HTTP_GET, LLSD());
 }
 
 LLSD LLHTTPClient::blockingPost(const std::string& url, const LLSD& body)
 {
-	return blocking_request(url, LLURLRequest::HTTP_POST, body);
+	return blocking_request(url, HTTP_POST, body);
 }
 
 void LLHTTPClient::put(
@@ -546,7 +553,7 @@ void LLHTTPClient::put(
 	const LLSD& headers,
 	const F32 timeout)
 {
-	request(url, LLURLRequest::HTTP_PUT, new LLSDInjector(body), responder, timeout, headers);
+	request(url, HTTP_PUT, new LLSDInjector(body), responder, timeout, headers);
 }
 
 void LLHTTPClient::post(
@@ -556,7 +563,7 @@ void LLHTTPClient::post(
 	const LLSD& headers,
 	const F32 timeout)
 {
-	request(url, LLURLRequest::HTTP_POST, new LLSDInjector(body), responder, timeout, headers);
+	request(url, HTTP_POST, new LLSDInjector(body), responder, timeout, headers);
 }
 
 void LLHTTPClient::postRaw(
@@ -567,7 +574,7 @@ void LLHTTPClient::postRaw(
 	const LLSD& headers,
 	const F32 timeout)
 {
-	request(url, LLURLRequest::HTTP_POST, new RawInjector(data, size), responder, timeout, headers);
+	request(url, HTTP_POST, new RawInjector(data, size), responder, timeout, headers);
 }
 
 void LLHTTPClient::postFile(
@@ -577,7 +584,7 @@ void LLHTTPClient::postFile(
 	const LLSD& headers,
 	const F32 timeout)
 {
-	request(url, LLURLRequest::HTTP_POST, new FileInjector(filename), responder, timeout, headers);
+	request(url, HTTP_POST, new FileInjector(filename), responder, timeout, headers);
 }
 
 void LLHTTPClient::postFile(
@@ -588,7 +595,7 @@ void LLHTTPClient::postFile(
 	const LLSD& headers,
 	const F32 timeout)
 {
-	request(url, LLURLRequest::HTTP_POST, new VFileInjector(uuid, asset_type), responder, timeout, headers);
+	request(url, HTTP_POST, new VFileInjector(uuid, asset_type), responder, timeout, headers);
 }
 
 // static
@@ -598,7 +605,7 @@ void LLHTTPClient::del(
 	const LLSD& headers,
 	const F32 timeout)
 {
-	request(url, LLURLRequest::HTTP_DELETE, NULL, responder, timeout, headers);
+	request(url, HTTP_DELETE, NULL, responder, timeout, headers);
 }
 
 // static
@@ -610,8 +617,8 @@ void LLHTTPClient::move(
 	const F32 timeout)
 {
 	LLSD headers = hdrs;
-	headers["Destination"] = destination;
-	request(url, LLURLRequest::HTTP_MOVE, NULL, responder, timeout, headers);
+	headers[HTTP_HEADER_DESTINATION] = destination;
+	request(url, HTTP_MOVE, NULL, responder, timeout, headers);
 }
 
 
diff --git a/indra/llmessage/llhttpclientadapter.cpp b/indra/llmessage/llhttpclientadapter.cpp
index f5d7a9abb6019442ad932e66237b39342fe788d1..aaa31e36fc68102ff3af3d65b9464ad94d1b0d55 100644
--- a/indra/llmessage/llhttpclientadapter.cpp
+++ b/indra/llmessage/llhttpclientadapter.cpp
@@ -35,16 +35,19 @@ void LLHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr respo
 {
 	LLSD empty_pragma_header;
 	// Pragma is required to stop curl adding "no-cache"
-	// Space is required to stop llurlrequest from turnning off proxying
-	empty_pragma_header["Pragma"] = " "; 
+	// Space is required to stop llurlrequest from turning off proxying
+	empty_pragma_header[HTTP_HEADER_PRAGMA] = " "; 
 	LLHTTPClient::get(url, responder, empty_pragma_header);
 }
 
 void LLHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers) 
 {
 	LLSD empty_pragma_header = headers;
-	// as above
-	empty_pragma_header["Pragma"] = " ";
+	if (!empty_pragma_header.has(HTTP_HEADER_PRAGMA))
+	{
+		// as above
+		empty_pragma_header[HTTP_HEADER_PRAGMA] = " ";
+	}
 	LLHTTPClient::get(url, responder, empty_pragma_header);
 }
 
@@ -53,3 +56,18 @@ void LLHTTPClientAdapter::put(const std::string& url, const LLSD& body, LLCurl::
 	LLHTTPClient::put(url, body, responder);
 }
 
+void LLHTTPClientAdapter::put(
+		const std::string& url,
+		const LLSD& body,
+		LLCurl::ResponderPtr responder,
+		const LLSD& headers)
+{
+	LLHTTPClient::put(url, body, responder, headers);
+}
+
+void LLHTTPClientAdapter::del(
+	const std::string& url,
+	LLCurl::ResponderPtr responder)
+{
+	LLHTTPClient::del(url, responder);
+}
diff --git a/indra/llmessage/llhttpclientadapter.h b/indra/llmessage/llhttpclientadapter.h
index aae6426a5921646cbf2768324c103cd21d39de96..270282c66fb43ed6ee2a516d7572e744e226e6ed 100644
--- a/indra/llmessage/llhttpclientadapter.h
+++ b/indra/llmessage/llhttpclientadapter.h
@@ -37,6 +37,14 @@ class LLHTTPClientAdapter : public LLHTTPClientInterface, public LLSingleton<LLH
 	virtual void get(const std::string& url, LLCurl::ResponderPtr responder);
 	virtual void get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers);
 	virtual void put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder);
+	virtual void put(
+		const std::string& url,
+		const LLSD& body,
+		LLCurl::ResponderPtr responder,
+		const LLSD& headers);
+	virtual void del(
+		const std::string& url,
+		LLCurl::ResponderPtr responder);
 };
 
 #endif
diff --git a/indra/llmessage/llhttpconstants.cpp b/indra/llmessage/llhttpconstants.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2134024a148b3db7fe08a47ea867f0b720310b34
--- /dev/null
+++ b/indra/llmessage/llhttpconstants.cpp
@@ -0,0 +1,219 @@
+/** 
+ * @file llhttpconstants.cpp
+ * @brief Implementation of the HTTP request / response constant lookups
+ *
+ * $LicenseInfo:firstyear=2013&license=viewergpl$
+ * 
+ * Copyright (c) 2013, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "llhttpconstants.h"
+#include "lltimer.h"
+
+// for curl_getdate() (apparently parsing RFC 1123 dates is hard)
+#include <curl/curl.h>
+
+const std::string HTTP_HEADER_ACCEPT("Accept");
+const std::string HTTP_HEADER_ACCEPT_CHARSET("Accept-Charset");
+const std::string HTTP_HEADER_ACCEPT_ENCODING("Accept-Encoding");
+const std::string HTTP_HEADER_ACCEPT_LANGUAGE("Accept-Language");
+const std::string HTTP_HEADER_ACCEPT_RANGES("Accept-Ranges");
+const std::string HTTP_HEADER_AGE("Age");
+const std::string HTTP_HEADER_ALLOW("Allow");
+const std::string HTTP_HEADER_AUTHORIZATION("Authorization");
+const std::string HTTP_HEADER_CACHE_CONTROL("Cache-Control");
+const std::string HTTP_HEADER_CONNECTION("Connection");
+const std::string HTTP_HEADER_CONTENT_DESCRIPTION("Content-Description");
+const std::string HTTP_HEADER_CONTENT_ENCODING("Content-Encoding");
+const std::string HTTP_HEADER_CONTENT_ID("Content-ID");
+const std::string HTTP_HEADER_CONTENT_LANGUAGE("Content-Language");
+const std::string HTTP_HEADER_CONTENT_LENGTH("Content-Length");
+const std::string HTTP_HEADER_CONTENT_LOCATION("Content-Location");
+const std::string HTTP_HEADER_CONTENT_MD5("Content-MD5");
+const std::string HTTP_HEADER_CONTENT_RANGE("Content-Range");
+const std::string HTTP_HEADER_CONTENT_TRANSFER_ENCODING("Content-Transfer-Encoding");
+const std::string HTTP_HEADER_CONTENT_TYPE("Content-Type");
+const std::string HTTP_HEADER_COOKIE("Cookie");
+const std::string HTTP_HEADER_DATE("Date");
+const std::string HTTP_HEADER_DESTINATION("Destination");
+const std::string HTTP_HEADER_ETAG("ETag");
+const std::string HTTP_HEADER_EXPECT("Expect");
+const std::string HTTP_HEADER_EXPIRES("Expires");
+const std::string HTTP_HEADER_FROM("From");
+const std::string HTTP_HEADER_HOST("Host");
+const std::string HTTP_HEADER_IF_MATCH("If-Match");
+const std::string HTTP_HEADER_IF_MODIFIED_SINCE("If-Modified-Since");
+const std::string HTTP_HEADER_IF_NONE_MATCH("If-None-Match");
+const std::string HTTP_HEADER_IF_RANGE("If-Range");
+const std::string HTTP_HEADER_IF_UNMODIFIED_SINCE("If-Unmodified-Since");
+const std::string HTTP_HEADER_KEEP_ALIVE("Keep-Alive");
+const std::string HTTP_HEADER_LAST_MODIFIED("Last-Modified");
+const std::string HTTP_HEADER_LOCATION("Location");
+const std::string HTTP_HEADER_MAX_FORWARDS("Max-Forwards");
+const std::string HTTP_HEADER_MIME_VERSION("MIME-Version");
+const std::string HTTP_HEADER_PRAGMA("Pragma");
+const std::string HTTP_HEADER_PROXY_AUTHENTICATE("Proxy-Authenticate");
+const std::string HTTP_HEADER_PROXY_AUTHORIZATION("Proxy-Authorization");
+const std::string HTTP_HEADER_RANGE("Range");
+const std::string HTTP_HEADER_REFERER("Referer");
+const std::string HTTP_HEADER_RETRY_AFTER("Retry-After");
+const std::string HTTP_HEADER_SERVER("Server");
+const std::string HTTP_HEADER_SET_COOKIE("Set-Cookie");
+const std::string HTTP_HEADER_TE("TE");
+const std::string HTTP_HEADER_TRAILER("Trailer");
+const std::string HTTP_HEADER_TRANSFER_ENCODING("Transfer-Encoding");
+const std::string HTTP_HEADER_UPGRADE("Upgrade");
+const std::string HTTP_HEADER_USER_AGENT("User-Agent");
+const std::string HTTP_HEADER_VARY("Vary");
+const std::string HTTP_HEADER_VIA("Via");
+const std::string HTTP_HEADER_WARNING("Warning");
+const std::string HTTP_HEADER_WWW_AUTHENTICATE("WWW-Authenticate");
+
+
+// Sadly, our proxied headers do not follow http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
+// We need to deal with lowercase headers
+const std::string HTTP_HEADER_LOWER_ACCEPT_LANGUAGE("accept-language");
+const std::string HTTP_HEADER_LOWER_CACHE_CONTROL("cache-control");
+const std::string HTTP_HEADER_LOWER_CONTENT_LENGTH("content-length");
+const std::string HTTP_HEADER_LOWER_CONTENT_TYPE("content-type");
+const std::string HTTP_HEADER_LOWER_HOST("host");
+const std::string HTTP_HEADER_LOWER_USER_AGENT("user-agent");
+const std::string HTTP_HEADER_LOWER_X_FORWARDED_FOR("x-forwarded-for");
+
+const std::string HTTP_CONTENT_LLSD_XML("application/llsd+xml");
+const std::string HTTP_CONTENT_OCTET_STREAM("application/octet-stream");
+const std::string HTTP_CONTENT_XML("application/xml");
+const std::string HTTP_CONTENT_JSON("application/json");
+const std::string HTTP_CONTENT_TEXT_HTML("text/html");
+const std::string HTTP_CONTENT_TEXT_HTML_UTF8("text/html; charset=utf-8");
+const std::string HTTP_CONTENT_TEXT_PLAIN_UTF8("text/plain; charset=utf-8");
+const std::string HTTP_CONTENT_TEXT_LLSD("text/llsd");
+const std::string HTTP_CONTENT_TEXT_XML("text/xml");
+const std::string HTTP_CONTENT_TEXT_LSL("text/lsl");
+const std::string HTTP_CONTENT_TEXT_PLAIN("text/plain");
+const std::string HTTP_CONTENT_IMAGE_X_J2C("image/x-j2c");
+const std::string HTTP_CONTENT_IMAGE_J2C("image/j2c");
+const std::string HTTP_CONTENT_IMAGE_JPEG("image/jpeg");
+const std::string HTTP_CONTENT_IMAGE_PNG("image/png");
+const std::string HTTP_CONTENT_IMAGE_BMP("image/bmp");
+
+const std::string HTTP_VERB_INVALID("(invalid)");
+const std::string HTTP_VERB_HEAD("HEAD");
+const std::string HTTP_VERB_GET("GET");
+const std::string HTTP_VERB_PUT("PUT");
+const std::string HTTP_VERB_POST("POST");
+const std::string HTTP_VERB_DELETE("DELETE");
+const std::string HTTP_VERB_MOVE("MOVE");
+const std::string HTTP_VERB_OPTIONS("OPTIONS");
+
+const std::string& httpMethodAsVerb(EHTTPMethod method)
+{
+	static const std::string VERBS[] =
+	{
+		HTTP_VERB_INVALID,
+		HTTP_VERB_HEAD,
+		HTTP_VERB_GET,
+		HTTP_VERB_PUT,
+		HTTP_VERB_POST,
+		HTTP_VERB_DELETE,
+		HTTP_VERB_MOVE,
+		HTTP_VERB_OPTIONS
+	};
+	if(((S32)method <=0) || ((S32)method >= HTTP_METHOD_COUNT))
+	{
+		return VERBS[0];
+	}
+	return VERBS[method];
+}
+
+bool isHttpInformationalStatus(S32 status)
+{
+	// Check for status 1xx.
+	return((100 <= status) && (status < 200));
+}
+
+bool isHttpGoodStatus(S32 status)
+{
+	// Check for status 2xx.
+	return((200 <= status) && (status < 300));
+}
+
+bool isHttpRedirectStatus(S32 status)
+{
+	// Check for status 3xx.
+	return((300 <= status) && (status < 400));
+}
+
+bool isHttpClientErrorStatus(S32 status)
+{
+	// Status 499 is sometimes used for re-interpreted status 2xx errors
+	// based on body content.  Treat these as potentially retryable 'server' status errors,
+	// since we do not have enough context to know if this will always fail.
+	if (HTTP_INTERNAL_ERROR == status) return false;
+
+	// Check for status 5xx.
+	return((400 <= status) && (status < 500));
+}
+
+bool isHttpServerErrorStatus(S32 status)
+{
+	// Status 499 is sometimes used for re-interpreted status 2xx errors.
+	// Allow retry of these, since we don't have enough information in this
+	// context to know if this will always fail.
+	if (HTTP_INTERNAL_ERROR == status) return true;
+
+	// Check for status 5xx.
+	return((500 <= status) && (status < 600));
+}
+
+// Parses 'Retry-After' header contents and returns seconds until retry should occur.
+bool getSecondsUntilRetryAfter(const std::string& retry_after, F32& seconds_to_wait)
+{
+	// *TODO:  This needs testing!   Not in use yet.
+	// Examples of Retry-After headers:
+	// Retry-After: Fri, 31 Dec 1999 23:59:59 GMT
+	// Retry-After: 120
+
+	// Check for number of seconds version, first:
+	char* end = 0;
+	// Parse as double
+	double seconds = std::strtod(retry_after.c_str(), &end);
+	if ( end != 0 && *end == 0 )
+	{
+		// Successful parse
+		seconds_to_wait = (F32) seconds;
+		return true;
+	}
+
+	// Parse rfc1123 date.
+	time_t date = curl_getdate(retry_after.c_str(), NULL );
+	if (-1 == date) return false;
+
+	seconds_to_wait = (F32)date - (F32)LLTimer::getTotalSeconds();
+	return true;
+}
+
diff --git a/indra/llmessage/llhttpconstants.h b/indra/llmessage/llhttpconstants.h
new file mode 100644
index 0000000000000000000000000000000000000000..34263e17c86640190ca9b850fefb6ff7a0bc6e45
--- /dev/null
+++ b/indra/llmessage/llhttpconstants.h
@@ -0,0 +1,220 @@
+/** 
+ * @file llhttpconstants.h
+ * @brief Constants for HTTP requests and responses
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ * 
+ * Copyright (c) 2001-2013, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_HTTP_CONSTANTS_H
+#define LL_HTTP_CONSTANTS_H
+
+#include "stdtypes.h"
+
+/////// HTTP STATUS CODES ///////
+
+// Standard errors from HTTP spec:
+// http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1
+const S32 HTTP_CONTINUE = 100;
+const S32 HTTP_SWITCHING_PROTOCOLS = 101;
+
+// Success
+const S32 HTTP_OK = 200;
+const S32 HTTP_CREATED = 201;
+const S32 HTTP_ACCEPTED = 202;
+const S32 HTTP_NON_AUTHORITATIVE_INFORMATION = 203;
+const S32 HTTP_NO_CONTENT = 204;
+const S32 HTTP_RESET_CONTENT = 205;
+const S32 HTTP_PARTIAL_CONTENT = 206;
+
+// Redirection
+const S32 HTTP_MULTIPLE_CHOICES = 300;
+const S32 HTTP_MOVED_PERMANENTLY = 301;
+const S32 HTTP_FOUND = 302;
+const S32 HTTP_SEE_OTHER = 303;
+const S32 HTTP_NOT_MODIFIED = 304;
+const S32 HTTP_USE_PROXY = 305;
+const S32 HTTP_TEMPORARY_REDIRECT = 307;
+
+// Client Error
+const S32 HTTP_BAD_REQUEST = 400;
+const S32 HTTP_UNAUTHORIZED = 401;
+const S32 HTTP_PAYMENT_REQUIRED = 402;
+const S32 HTTP_FORBIDDEN = 403;
+const S32 HTTP_NOT_FOUND = 404;
+const S32 HTTP_METHOD_NOT_ALLOWED = 405;
+const S32 HTTP_NOT_ACCEPTABLE = 406;
+const S32 HTTP_PROXY_AUTHENTICATION_REQUIRED = 407;
+const S32 HTTP_REQUEST_TIME_OUT = 408;
+const S32 HTTP_CONFLICT = 409;
+const S32 HTTP_GONE = 410;
+const S32 HTTP_LENGTH_REQUIRED = 411;
+const S32 HTTP_PRECONDITION_FAILED = 412;
+const S32 HTTP_REQUEST_ENTITY_TOO_LARGE = 413;
+const S32 HTTP_REQUEST_URI_TOO_LARGE = 414;
+const S32 HTTP_UNSUPPORTED_MEDIA_TYPE = 415;
+const S32 HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
+const S32 HTTP_EXPECTATION_FAILED = 417;
+
+// Server Error
+const S32 HTTP_INTERNAL_SERVER_ERROR = 500;
+const S32 HTTP_NOT_IMPLEMENTED = 501;
+const S32 HTTP_BAD_GATEWAY = 502;
+const S32 HTTP_SERVICE_UNAVAILABLE = 503;
+const S32 HTTP_GATEWAY_TIME_OUT = 504;
+const S32 HTTP_VERSION_NOT_SUPPORTED = 505;
+
+// We combine internal process errors with status codes
+// These status codes should not be sent over the wire
+//   and indicate something went wrong internally.
+// If you get these they are not normal.
+const S32 HTTP_INTERNAL_CURL_ERROR = 498;
+const S32 HTTP_INTERNAL_ERROR = 499;
+
+
+////// HTTP Methods //////
+
+extern const std::string HTTP_VERB_INVALID;
+extern const std::string HTTP_VERB_HEAD;
+extern const std::string HTTP_VERB_GET;
+extern const std::string HTTP_VERB_PUT;
+extern const std::string HTTP_VERB_POST;
+extern const std::string HTTP_VERB_DELETE;
+extern const std::string HTTP_VERB_MOVE;
+extern const std::string HTTP_VERB_OPTIONS;
+
+enum EHTTPMethod
+{
+	HTTP_INVALID = 0,
+	HTTP_HEAD,
+	HTTP_GET,
+	HTTP_PUT,
+	HTTP_POST,
+	HTTP_DELETE,
+	HTTP_MOVE, // Caller will need to set 'Destination' header
+	HTTP_OPTIONS,
+	HTTP_METHOD_COUNT
+};
+
+const std::string& httpMethodAsVerb(EHTTPMethod method);
+bool isHttpInformationalStatus(S32 status);
+bool isHttpGoodStatus(S32 status);
+bool isHttpRedirectStatus(S32 status);
+bool isHttpClientErrorStatus(S32 status);
+bool isHttpServerErrorStatus(S32 status);
+
+// Parses 'Retry-After' header contents and returns seconds until retry should occur.
+bool getSecondsUntilRetryAfter(const std::string& retry_after, F32& seconds_to_wait);
+
+//// HTTP Headers /////
+
+extern const std::string HTTP_HEADER_ACCEPT;
+extern const std::string HTTP_HEADER_ACCEPT_CHARSET;
+extern const std::string HTTP_HEADER_ACCEPT_ENCODING;
+extern const std::string HTTP_HEADER_ACCEPT_LANGUAGE;
+extern const std::string HTTP_HEADER_ACCEPT_RANGES;
+extern const std::string HTTP_HEADER_AGE;
+extern const std::string HTTP_HEADER_ALLOW;
+extern const std::string HTTP_HEADER_AUTHORIZATION;
+extern const std::string HTTP_HEADER_CACHE_CONTROL;
+extern const std::string HTTP_HEADER_CONNECTION;
+extern const std::string HTTP_HEADER_CONTENT_DESCRIPTION;
+extern const std::string HTTP_HEADER_CONTENT_ENCODING;
+extern const std::string HTTP_HEADER_CONTENT_ID;
+extern const std::string HTTP_HEADER_CONTENT_LANGUAGE;
+extern const std::string HTTP_HEADER_CONTENT_LENGTH;
+extern const std::string HTTP_HEADER_CONTENT_LOCATION;
+extern const std::string HTTP_HEADER_CONTENT_MD5;
+extern const std::string HTTP_HEADER_CONTENT_RANGE;
+extern const std::string HTTP_HEADER_CONTENT_TRANSFER_ENCODING;
+extern const std::string HTTP_HEADER_CONTENT_TYPE;
+extern const std::string HTTP_HEADER_COOKIE;
+extern const std::string HTTP_HEADER_DATE;
+extern const std::string HTTP_HEADER_DESTINATION;
+extern const std::string HTTP_HEADER_ETAG;
+extern const std::string HTTP_HEADER_EXPECT;
+extern const std::string HTTP_HEADER_EXPIRES;
+extern const std::string HTTP_HEADER_FROM;
+extern const std::string HTTP_HEADER_HOST;
+extern const std::string HTTP_HEADER_IF_MATCH;
+extern const std::string HTTP_HEADER_IF_MODIFIED_SINCE;
+extern const std::string HTTP_HEADER_IF_NONE_MATCH;
+extern const std::string HTTP_HEADER_IF_RANGE;
+extern const std::string HTTP_HEADER_IF_UNMODIFIED_SINCE;
+extern const std::string HTTP_HEADER_KEEP_ALIVE;
+extern const std::string HTTP_HEADER_LAST_MODIFIED;
+extern const std::string HTTP_HEADER_LOCATION;
+extern const std::string HTTP_HEADER_MAX_FORWARDS;
+extern const std::string HTTP_HEADER_MIME_VERSION;
+extern const std::string HTTP_HEADER_PRAGMA;
+extern const std::string HTTP_HEADER_PROXY_AUTHENTICATE;
+extern const std::string HTTP_HEADER_PROXY_AUTHORIZATION;
+extern const std::string HTTP_HEADER_RANGE;
+extern const std::string HTTP_HEADER_REFERER;
+extern const std::string HTTP_HEADER_RETRY_AFTER;
+extern const std::string HTTP_HEADER_SERVER;
+extern const std::string HTTP_HEADER_SET_COOKIE;
+extern const std::string HTTP_HEADER_TE;
+extern const std::string HTTP_HEADER_TRAILER;
+extern const std::string HTTP_HEADER_TRANSFER_ENCODING;
+extern const std::string HTTP_HEADER_UPGRADE;
+extern const std::string HTTP_HEADER_USER_AGENT;
+extern const std::string HTTP_HEADER_VARY;
+extern const std::string HTTP_HEADER_VIA;
+extern const std::string HTTP_HEADER_WARNING;
+extern const std::string HTTP_HEADER_WWW_AUTHENTICATE;
+
+// Sadly, our proxied headers do not follow http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
+// We need to deal with lowercase headers
+extern const std::string HTTP_HEADER_LOWER_ACCEPT_LANGUAGE;
+extern const std::string HTTP_HEADER_LOWER_CACHE_CONTROL;
+extern const std::string HTTP_HEADER_LOWER_CONTENT_LENGTH;
+extern const std::string HTTP_HEADER_LOWER_CONTENT_TYPE;
+extern const std::string HTTP_HEADER_LOWER_HOST;
+extern const std::string HTTP_HEADER_LOWER_USER_AGENT;
+extern const std::string HTTP_HEADER_LOWER_X_FORWARDED_FOR;
+
+//// HTTP Content Types ////
+
+extern const std::string HTTP_CONTENT_LLSD_XML;
+extern const std::string HTTP_CONTENT_OCTET_STREAM;
+extern const std::string HTTP_CONTENT_XML;
+extern const std::string HTTP_CONTENT_JSON;
+extern const std::string HTTP_CONTENT_TEXT_HTML;
+extern const std::string HTTP_CONTENT_TEXT_HTML_UTF8;
+extern const std::string HTTP_CONTENT_TEXT_PLAIN_UTF8;
+extern const std::string HTTP_CONTENT_TEXT_LLSD;
+extern const std::string HTTP_CONTENT_TEXT_XML;
+extern const std::string HTTP_CONTENT_TEXT_LSL;
+extern const std::string HTTP_CONTENT_TEXT_PLAIN;
+extern const std::string HTTP_CONTENT_IMAGE_X_J2C;
+extern const std::string HTTP_CONTENT_IMAGE_J2C;
+extern const std::string HTTP_CONTENT_IMAGE_JPEG;
+extern const std::string HTTP_CONTENT_IMAGE_PNG;
+extern const std::string HTTP_CONTENT_IMAGE_BMP;
+
+#endif
diff --git a/indra/llmessage/llhttpnode.cpp b/indra/llmessage/llhttpnode.cpp
index 5c2f73eccb809bb32e50900ec9fd23f0139b4596..e3b42b1b1641aafe937371eb250449cd17df71b1 100644
--- a/indra/llmessage/llhttpnode.cpp
+++ b/indra/llmessage/llhttpnode.cpp
@@ -30,6 +30,7 @@
 #include <boost/tokenizer.hpp>
 
 #include "llstl.h"
+#include "llhttpconstants.h"
 #include "lliohttpserver.h" // for string constants
 
 static const std::string CONTEXT_WILDCARD("wildcard");
@@ -173,13 +174,15 @@ LLSD LLHTTPNode::simpleDel(const LLSD&) const
 void  LLHTTPNode::options(ResponsePtr response, const LLSD& context) const
 {
 	//llinfos << "options context: " << context << llendl;
+	LL_DEBUGS("LLHTTPNode") << "context: " << context << LL_ENDL;
 
 	// default implementation constructs an url to the documentation.
+	// *TODO: Check for 'Host' header instead of 'host' header?
 	std::string host(
-		context[CONTEXT_REQUEST][CONTEXT_HEADERS]["host"].asString());
+		context[CONTEXT_REQUEST][CONTEXT_HEADERS][HTTP_HEADER_LOWER_HOST].asString());
 	if(host.empty())
 	{
-		response->status(400, "Bad Request -- need Host header");
+		response->status(HTTP_BAD_REQUEST, "Bad Request -- need Host header");
 		return;
 	}
 	std::ostringstream ostr;
@@ -187,7 +190,7 @@ void  LLHTTPNode::options(ResponsePtr response, const LLSD& context) const
 	ostr << context[CONTEXT_REQUEST]["path"].asString();
 	static const std::string DOC_HEADER("X-Documentation-URL");
 	response->addHeader(DOC_HEADER, ostr.str());
-	response->status(200, "OK");
+	response->status(HTTP_OK, "OK");
 }
 
 
@@ -389,17 +392,17 @@ void LLHTTPNode::Response::statusUnknownError(S32 code)
 
 void LLHTTPNode::Response::notFound(const std::string& message)
 {
-	status(404, message);
+	status(HTTP_NOT_FOUND, message);
 }
 
 void LLHTTPNode::Response::notFound()
 {
-	status(404, "Not Found");
+	status(HTTP_NOT_FOUND, "Not Found");
 }
 
 void LLHTTPNode::Response::methodNotAllowed()
 {
-	status(405, "Method Not Allowed");
+	status(HTTP_METHOD_NOT_ALLOWED, "Method Not Allowed");
 }
 
 void LLHTTPNode::Response::addHeader(
@@ -467,7 +470,7 @@ LLSimpleResponse::~LLSimpleResponse()
 
 void LLSimpleResponse::result(const LLSD& result)
 {
-	status(200, "OK");
+	status(HTTP_OK, "OK");
 }
 
 void LLSimpleResponse::extendedResult(S32 code, const std::string& body, const LLSD& headers)
@@ -475,6 +478,11 @@ void LLSimpleResponse::extendedResult(S32 code, const std::string& body, const L
 	status(code,body);
 }
 
+void LLSimpleResponse::extendedResult(S32 code, const LLSD& r, const LLSD& headers)
+{
+	status(code,"(LLSD)");
+}
+
 void LLSimpleResponse::status(S32 code, const std::string& message)
 {
 	mCode = code;
diff --git a/indra/llmessage/llhttpnode.h b/indra/llmessage/llhttpnode.h
index 148647ddde16ecbc76fb3fa4dc138a285a876933..2539eec6c3f8aa346b0bc092577f1b57c78ff22c 100644
--- a/indra/llmessage/llhttpnode.h
+++ b/indra/llmessage/llhttpnode.h
@@ -60,6 +60,8 @@ class LLChainIOFactory;
  */
 class LLHTTPNode
 {
+protected:
+    LOG_CLASS(LLHTTPNode);
 public:
 	LLHTTPNode();
 	virtual ~LLHTTPNode();
@@ -100,7 +102,12 @@ class LLHTTPNode
 		/**
 		 * @brief return status code and message with headers.
 		 */
-		virtual void extendedResult(S32 code, const std::string& message, const LLSD& headers) = 0;
+		virtual void extendedResult(S32 code, const std::string& message, const LLSD& headers = LLSD()) = 0;
+
+		/**
+		 * @brief return status code and LLSD result with headers.
+		 */
+		virtual void extendedResult(S32 code, const LLSD& result, const LLSD& headers = LLSD()) = 0;
 
 		/**
 		 * @brief return status code and reason string on http header,
@@ -287,7 +294,7 @@ class LLSimpleResponse : public LLHTTPNode::Response
 	
 	void result(const LLSD& result);
 	void extendedResult(S32 code, const std::string& body, const LLSD& headers);
-	
+	void extendedResult(S32 code, const LLSD& result, const LLSD& headers);
 	void status(S32 code, const std::string& message);
 
 	void print(std::ostream& out) const;
diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp
index 1236fc8b71c917c30a37bfdd7d9f3274241172d7..509719786c29b2f9a59d190f698294706ab06447 100644
--- a/indra/llmessage/lliohttpserver.cpp
+++ b/indra/llmessage/lliohttpserver.cpp
@@ -33,6 +33,7 @@
 #include "llapr.h"
 #include "llbuffer.h"
 #include "llbufferstream.h"
+#include "llhttpconstants.h"
 #include "llhttpnode.h"
 #include "lliopipe.h"
 #include "lliosocket.h"
@@ -53,11 +54,6 @@ const std::string CONTEXT_REQUEST("request");
 const std::string CONTEXT_RESPONSE("response");
 const std::string CONTEXT_VERB("verb");
 const std::string CONTEXT_HEADERS("headers");
-const std::string HTTP_VERB_GET("GET");
-const std::string HTTP_VERB_PUT("PUT");
-const std::string HTTP_VERB_POST("POST");
-const std::string HTTP_VERB_DELETE("DELETE");
-const std::string HTTP_VERB_OPTIONS("OPTIONS");
 
 static LLIOHTTPServer::timing_callback_t sTimingCallback = NULL;
 static void* sTimingCallbackData = NULL;
@@ -102,7 +98,7 @@ class LLHTTPPipe : public LLIOPipe
 		// from LLHTTPNode::Response
 		virtual void result(const LLSD&);
 		virtual void extendedResult(S32 code, const std::string& body, const LLSD& headers);
-		
+		virtual void extendedResult(S32 code, const LLSD& body, const LLSD& headers);
 		virtual void status(S32 code, const std::string& message);
 
 		void nullPipe();
@@ -122,7 +118,8 @@ class LLHTTPPipe : public LLIOPipe
 		STATE_LOCKED,
 		STATE_GOOD_RESULT,
 		STATE_STATUS_RESULT,
-		STATE_EXTENDED_RESULT
+		STATE_EXTENDED_RESULT,
+		STATE_EXTENDED_LLSD_RESULT
 	};
 	State mState;
 
@@ -132,7 +129,7 @@ class LLHTTPPipe : public LLIOPipe
 	void lockChain(LLPumpIO*);
 	void unlockChain();
 
-	LLSD mGoodResult;
+	LLSD mResult;
 	S32 mStatusCode;
 	std::string mStatusMessage;	
 	LLSD mHeaders;
@@ -193,7 +190,7 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
 			}
 			else if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_TEXT)
 			{
-				std::stringstream strstrm;
+				std::ostringstream strstrm;
 				strstrm << istr.rdbuf();
 				input = strstrm.str();
 			}
@@ -209,7 +206,7 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
 			}
 			else if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_TEXT)
 			{
-				std::stringstream strstrm;
+				std::ostringstream strstrm;
 				strstrm << istr.rdbuf();
 				input = strstrm.str();
 			}
@@ -249,7 +246,7 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
 			<< "s" << llendl;
 
 		// Log Internal Server Errors
-		//if(mStatusCode == 500)
+		//if(mStatusCode == HTTP_INTERNAL_SERVER_ERROR)
 		//{
 		//	llwarns << "LLHTTPPipe::process_impl:500:Internal Server Error" 
 		//			<< llendl;
@@ -271,10 +268,10 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
 		case STATE_GOOD_RESULT:
 		{
 			LLSD headers = mHeaders;
-			headers["Content-Type"] = "application/llsd+xml";
+			headers[HTTP_HEADER_CONTENT_TYPE] = HTTP_CONTENT_LLSD_XML;
 			context[CONTEXT_RESPONSE][CONTEXT_HEADERS] = headers;
 			LLBufferStream ostr(channels, buffer.get());
-			LLSDSerialize::toXML(mGoodResult, ostr);
+			LLSDSerialize::toXML(mResult, ostr);
 
 			return STATUS_DONE;
 		}
@@ -282,7 +279,7 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
 		case STATE_STATUS_RESULT:
 		{
 			LLSD headers = mHeaders;
-			headers["Content-Type"] = "text/plain";
+			headers[HTTP_HEADER_CONTENT_TYPE] = HTTP_CONTENT_TEXT_PLAIN;
 			context[CONTEXT_RESPONSE][CONTEXT_HEADERS] = headers;
 			context[CONTEXT_RESPONSE]["statusCode"] = mStatusCode;
 			context[CONTEXT_RESPONSE]["statusMessage"] = mStatusMessage;
@@ -300,6 +297,17 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
 
 			return STATUS_DONE;
 		}
+		case STATE_EXTENDED_LLSD_RESULT:
+		{
+			LLSD headers = mHeaders;
+			headers[HTTP_HEADER_CONTENT_TYPE] = HTTP_CONTENT_LLSD_XML;
+			context[CONTEXT_RESPONSE][CONTEXT_HEADERS] = headers;
+			context[CONTEXT_RESPONSE]["statusCode"] = mStatusCode;
+			LLBufferStream ostr(channels, buffer.get());
+			LLSDSerialize::toXML(mResult, ostr);
+
+			return STATUS_DONE;
+		}
 		default:
 			llwarns << "LLHTTPPipe::process_impl: unexpected state "
 				<< mState << llendl;
@@ -335,19 +343,35 @@ void LLHTTPPipe::Response::result(const LLSD& r)
 		return;
 	}
 
-	mPipe->mStatusCode = 200;
+	mPipe->mStatusCode = HTTP_OK;
 	mPipe->mStatusMessage = "OK";
-	mPipe->mGoodResult = r;
+	mPipe->mResult = r;
 	mPipe->mState = STATE_GOOD_RESULT;
 	mPipe->mHeaders = mHeaders;
-	mPipe->unlockChain();	
+	mPipe->unlockChain();
+}
+
+void LLHTTPPipe::Response::extendedResult(S32 code, const LLSD& r, const LLSD& headers)
+{
+	if(! mPipe)
+	{
+		llwarns << "LLHTTPPipe::Response::extendedResult: NULL pipe" << llendl;
+		return;
+	}
+
+	mPipe->mStatusCode = code;
+	mPipe->mStatusMessage = "(LLSD)";
+	mPipe->mResult = r;
+	mPipe->mHeaders = headers;
+	mPipe->mState = STATE_EXTENDED_LLSD_RESULT;
+	mPipe->unlockChain();
 }
 
 void LLHTTPPipe::Response::extendedResult(S32 code, const std::string& body, const LLSD& headers)
 {
 	if(! mPipe)
 	{
-		llwarns << "LLHTTPPipe::Response::status: NULL pipe" << llendl;
+		llwarns << "LLHTTPPipe::Response::extendedResult: NULL pipe" << llendl;
 		return;
 	}
 
@@ -454,9 +478,9 @@ LLIOPipe::EStatus LLHTTPResponseHeader::process_impl(
 		std::string message = context[CONTEXT_RESPONSE]["statusMessage"];
 		
 		int code = context[CONTEXT_RESPONSE]["statusCode"];
-		if (code < 200)
+		if (code < HTTP_OK)
 		{
-			code = 200;
+			code = HTTP_OK;
 			message = "OK";
 		}
 		
@@ -465,7 +489,7 @@ LLIOPipe::EStatus LLHTTPResponseHeader::process_impl(
 		S32 content_length = buffer->countAfter(channels.in(), NULL);
 		if(0 < content_length)
 		{
-			ostr << "Content-Length: " << content_length << "\r\n";
+			ostr << HTTP_HEADER_CONTENT_LENGTH << ": " << content_length << "\r\n";
 		}
 		// *NOTE: This guard can go away once the LLSD static map
 		// iterator is available. Phoenix. 2008-05-09
@@ -771,7 +795,7 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl(
 					std::string name(buf, pos_colon - buf);
 					std::string value(pos_colon + 2);
 					LLStringUtil::toLower(name);
-					if("content-length" == name)
+					if(HTTP_HEADER_LOWER_CONTENT_LENGTH == name)
 					{
 						lldebugs << "Content-Length: " << value << llendl;
 						mContentLength = atoi(value.c_str());
diff --git a/indra/llmessage/lliohttpserver.h b/indra/llmessage/lliohttpserver.h
index 5c1b0531ff2693de45fd6b15147523e27f7e725f..40537e05bc6071360bb2b371848ca25a7ae40b8b 100644
--- a/indra/llmessage/lliohttpserver.h
+++ b/indra/llmessage/lliohttpserver.h
@@ -39,11 +39,6 @@ extern const std::string CONTEXT_REQUEST;
 extern const std::string CONTEXT_RESPONSE;
 extern const std::string CONTEXT_VERB;
 extern const std::string CONTEXT_HEADERS;
-extern const std::string HTTP_VERB_GET;
-extern const std::string HTTP_VERB_PUT;
-extern const std::string HTTP_VERB_POST;
-extern const std::string HTTP_VERB_DELETE;
-extern const std::string HTTP_VERB_OPTIONS;
 
 class LLIOHTTPServer
 {
diff --git a/indra/llmessage/llmime.cpp b/indra/llmessage/llmime.cpp
index 9d9c4ebd6899f8eb0c4292ae5b9d8bb3ad94f649..90653098db7abc3590d1ba90aee79fa932f14203 100644
--- a/indra/llmessage/llmime.cpp
+++ b/indra/llmessage/llmime.cpp
@@ -27,6 +27,7 @@
  */
 
 #include "linden_common.h"
+#include "llhttpconstants.h"
 #include "llmime.h"
 
 #include <vector>
@@ -36,20 +37,6 @@
 /**
  * Useful constants.
  */
-// Headers specified in rfc-2045 will be canonicalized below.
-static const std::string CONTENT_LENGTH("Content-Length");
-static const std::string CONTENT_TYPE("Content-Type");
-static const S32 KNOWN_HEADER_COUNT = 6;
-static const std::string KNOWN_HEADER[KNOWN_HEADER_COUNT] =
-{
-	CONTENT_LENGTH,
-	CONTENT_TYPE,
-	std::string("MIME-Version"),
-	std::string("Content-Transfer-Encoding"),
-	std::string("Content-ID"),
-	std::string("Content-Description"),
-};
-
 // parser helpers
 static const std::string MULTIPART("multipart");
 static const std::string BOUNDARY("boundary");
@@ -115,7 +102,7 @@ S32 LLMimeIndex::contentLength() const
 {
 	// Find the content length in the headers.
 	S32 length = -1;
-	LLSD content_length = mImpl->mHeaders[CONTENT_LENGTH];
+	LLSD content_length = mImpl->mHeaders[HTTP_HEADER_CONTENT_LENGTH];
 	if(content_length.isDefined())
 	{
 		length = content_length.asInteger();
@@ -126,7 +113,7 @@ S32 LLMimeIndex::contentLength() const
 std::string LLMimeIndex::contentType() const
 {
 	std::string type;
-	LLSD content_type = mImpl->mHeaders[CONTENT_TYPE];
+	LLSD content_type = mImpl->mHeaders[HTTP_HEADER_CONTENT_TYPE];
 	if(content_type.isDefined())
 	{
 		type = content_type.asString();
@@ -137,7 +124,7 @@ std::string LLMimeIndex::contentType() const
 bool LLMimeIndex::isMultipart() const
 {
 	bool multipart = false;
-	LLSD content_type = mImpl->mHeaders[CONTENT_TYPE];
+	LLSD content_type = mImpl->mHeaders[HTTP_HEADER_CONTENT_TYPE];
 	if(content_type.isDefined())
 	{
 		std::string type = content_type.asString();
@@ -354,7 +341,7 @@ bool LLMimeParser::Impl::parseIndex(
 		if(index.isMultipart())
 		{
 			// Figure out the separator, scan past it, and recurse.
-			std::string ct = headers[CONTENT_TYPE].asString();
+			std::string ct = headers[HTTP_HEADER_CONTENT_TYPE].asString();
 			std::string sep = findSeparator(ct);
 			scanPastSeparator(istr, limit, sep);
 			while(continueParse() && parseIndex(istr, limit, sep, true, mime))
@@ -381,6 +368,18 @@ bool LLMimeParser::Impl::parseHeaders(
 	S32 limit,
 	LLSD& headers)
 {
+	// Headers specified in rfc-2045 will be canonicalized below.
+	static const S32 KNOWN_HEADER_COUNT = 6;
+	static const std::string KNOWN_HEADER[KNOWN_HEADER_COUNT] =
+	{
+		HTTP_HEADER_CONTENT_LENGTH,
+		HTTP_HEADER_CONTENT_TYPE,
+		HTTP_HEADER_MIME_VERSION,
+		HTTP_HEADER_CONTENT_TRANSFER_ENCODING,
+		HTTP_HEADER_CONTENT_ID,
+		HTTP_HEADER_CONTENT_DESCRIPTION,
+	};
+
 	while(continueParse())
 	{
 		// Get the next line.
@@ -531,9 +530,9 @@ void LLMimeParser::Impl::scanPastContent(
 	LLSD headers,
 	const std::string separator)
 {
-	if(headers.has(CONTENT_LENGTH))
+	if(headers.has(HTTP_HEADER_CONTENT_LENGTH))
 	{
-		S32 content_length = headers[CONTENT_LENGTH].asInteger();
+		S32 content_length = headers[HTTP_HEADER_CONTENT_LENGTH].asInteger();
 		// Subtract 2 here for the \r\n after the content.
 		S32 max_skip = llmin(content_length, limit - mScanCount - 2);
 		istr.ignore(max_skip);
diff --git a/indra/llmessage/llregionpresenceverifier.cpp b/indra/llmessage/llregionpresenceverifier.cpp
deleted file mode 100644
index 932cbf375e3ec2a5e45d664a79f0810a642cc8bb..0000000000000000000000000000000000000000
--- a/indra/llmessage/llregionpresenceverifier.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/** 
- * @file llregionpresenceverifier.cpp
- * @brief 
- *
- * $LicenseInfo:firstyear=2008&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "linden_common.h"
-
-#include "llregionpresenceverifier.h"
-#include "llhttpclientinterface.h"
-#include <sstream>
-#include "net.h"
-#include "message.h"
-
-namespace boost
-{
-	void intrusive_ptr_add_ref(LLRegionPresenceVerifier::Response* p)
-	{
-		++p->mReferenceCount;
-	}
-	
-	void intrusive_ptr_release(LLRegionPresenceVerifier::Response* p)
-	{
-		if(p && 0 == --p->mReferenceCount)
-		{
-			delete p;
-		}
-	}
-};
-
-LLRegionPresenceVerifier::Response::~Response()
-{
-}
-
-LLRegionPresenceVerifier::RegionResponder::RegionResponder(const std::string&
-														   uri,
-														   ResponsePtr data,
-														   S32 retry_count) :
-	mUri(uri),
-	mSharedData(data),
-	mRetryCount(retry_count)
-{
-}
-
-//virtual
-LLRegionPresenceVerifier::RegionResponder::~RegionResponder()
-{
-}
-
-void LLRegionPresenceVerifier::RegionResponder::result(const LLSD& content)
-{
-	std::string host = content["private_host"].asString();
-	U32 port = content["private_port"].asInteger();
-	LLHost destination(host, port);
-	LLUUID id = content["region_id"];
-
-	lldebugs << "Verifying " << destination.getString() << " is region " << id << llendl;
-
-	std::stringstream uri;
-	uri << "http://" << destination.getString() << "/state/basic/";
-	mSharedData->getHttpClient().get(
-		uri.str(),
-		new VerifiedDestinationResponder(mUri, mSharedData, content, mRetryCount));
-}
-
-void LLRegionPresenceVerifier::RegionResponder::error(U32 status,
-													 const std::string& reason)
-{
-	// TODO: babbage: distinguish between region presence service and
-	// region verification errors?
-	mSharedData->onRegionVerificationFailed();
-}
-
-LLRegionPresenceVerifier::VerifiedDestinationResponder::VerifiedDestinationResponder(const std::string& uri, ResponsePtr data, const LLSD& content,
-	S32 retry_count):
-	mUri(uri),
-	mSharedData(data),
-	mContent(content),
-	mRetryCount(retry_count) 
-{
-}
-
-//virtual
-LLRegionPresenceVerifier::VerifiedDestinationResponder::~VerifiedDestinationResponder()
-{
-}
-
-void LLRegionPresenceVerifier::VerifiedDestinationResponder::result(const LLSD& content)
-{
-	LLUUID actual_region_id = content["region_id"];
-	LLUUID expected_region_id = mContent["region_id"];
-
-	lldebugs << "Actual region: " << content << llendl;
-	lldebugs << "Expected region: " << mContent << llendl;
-
-	if (mSharedData->checkValidity(content) &&
-		(actual_region_id == expected_region_id))
-	{
-		mSharedData->onRegionVerified(mContent);
-	}
-	else if (mRetryCount > 0)
-	{
-		retry();
-	}
-	else
-	{
-		llwarns << "Simulator verification failed. Region: " << mUri << llendl;
-		mSharedData->onRegionVerificationFailed();
-	}
-}
-
-void LLRegionPresenceVerifier::VerifiedDestinationResponder::retry()
-{
-	LLSD headers;
-	headers["Cache-Control"] = "no-cache, max-age=0";
-	llinfos << "Requesting region information, get uncached for region "
-			<< mUri << llendl;
-	--mRetryCount;
-	mSharedData->getHttpClient().get(mUri, new RegionResponder(mUri, mSharedData, mRetryCount), headers);
-}
-
-void LLRegionPresenceVerifier::VerifiedDestinationResponder::error(U32 status, const std::string& reason)
-{
-	if(mRetryCount > 0)
-	{
-		retry();
-	}
-	else
-	{
-		llwarns << "Failed to contact simulator for verification. Region: " << mUri << llendl;
-		mSharedData->onRegionVerificationFailed();
-	}
-}
diff --git a/indra/llmessage/llregionpresenceverifier.h b/indra/llmessage/llregionpresenceverifier.h
deleted file mode 100644
index 5e8251e519bc7b1a7b86adc2f592513935fbb0a8..0000000000000000000000000000000000000000
--- a/indra/llmessage/llregionpresenceverifier.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/** 
- * @file llregionpresenceverifier.cpp
- * @brief 
- *
- * $LicenseInfo:firstyear=2008&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-/* Macro Definitions */
-#ifndef LL_LLREGIONPRESENCEVERIFIER_H
-#define LL_LLREGIONPRESENCEVERIFIER_H
-
-#include "llhttpclient.h"
-#include <string>
-#include "llsd.h"
-#include <boost/intrusive_ptr.hpp>
-
-class LLHTTPClientInterface;
-
-class LLRegionPresenceVerifier
-{
-public:
-	class Response
-	{
-	public:
-		virtual ~Response() = 0;
-
-		virtual bool checkValidity(const LLSD& content) const = 0;
-		virtual void onRegionVerified(const LLSD& region_details) = 0;
-		virtual void onRegionVerificationFailed() = 0;
-
-		virtual LLHTTPClientInterface& getHttpClient() = 0;
-
-	public: /* but not really -- don't touch this */
-		U32 mReferenceCount;		
-	};
-
-	typedef boost::intrusive_ptr<Response> ResponsePtr;
-
-	class RegionResponder : public LLHTTPClient::Responder
-	{
-	public:
-		RegionResponder(const std::string& uri, ResponsePtr data,
-						S32 retry_count);
-		virtual ~RegionResponder(); 
-		virtual void result(const LLSD& content);
-		virtual void error(U32 status, const std::string& reason);
-
-	private:
-		ResponsePtr mSharedData;
-		std::string mUri;
-		S32 mRetryCount;
-	};
-
-	class VerifiedDestinationResponder : public LLHTTPClient::Responder
-	{
-	public:
-		VerifiedDestinationResponder(const std::string& uri, ResponsePtr data,
-									 const LLSD& content, S32 retry_count);
-		virtual ~VerifiedDestinationResponder();
-		virtual void result(const LLSD& content);
-		
-		virtual void error(U32 status, const std::string& reason);
-		
-	private:
-		void retry();
-		ResponsePtr mSharedData;
-		LLSD mContent;
-		std::string mUri;
-		S32 mRetryCount;
-	};
-};
-
-namespace boost
-{
-	void intrusive_ptr_add_ref(LLRegionPresenceVerifier::Response* p);
-	void intrusive_ptr_release(LLRegionPresenceVerifier::Response* p);
-};
-
-#endif //LL_LLREGIONPRESENCEVERIFIER_H
diff --git a/indra/llmessage/llsdmessage.cpp b/indra/llmessage/llsdmessage.cpp
index 1c93c12d990a35ca97e9ae2d4b97db73f0c0ba4d..376f69ea36bbdc36394bb19b6a67c4186b09d7ae 100644
--- a/indra/llmessage/llsdmessage.cpp
+++ b/indra/llmessage/llsdmessage.cpp
@@ -92,14 +92,14 @@ bool LLSDMessage::httpListener(const LLSD& request)
     return false;
 }
 
-void LLSDMessage::EventResponder::result(const LLSD& data)
+void LLSDMessage::EventResponder::httpSuccess()
 {
     // If our caller passed an empty replyPump name, they're not
     // listening: this is a fire-and-forget message. Don't bother posting
     // to the pump whose name is "".
     if (! mReplyPump.empty())
     {
-        LLSD response(data);
+        LLSD response(getContent());
         mReqID.stamp(response);
         mPumps.obtain(mReplyPump).post(response);
     }
@@ -111,7 +111,7 @@ void LLSDMessage::EventResponder::result(const LLSD& data)
     }
 }
 
-void LLSDMessage::EventResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+void LLSDMessage::EventResponder::httpFailure()
 {
     // If our caller passed an empty errorPump name, they're not
     // listening: "default error handling is acceptable." Only post to an
@@ -121,19 +121,16 @@ void LLSDMessage::EventResponder::errorWithContent(U32 status, const std::string
         LLSD info(mReqID.makeResponse());
         info["target"]  = mTarget;
         info["message"] = mMessage;
-        info["status"]  = LLSD::Integer(status);
-        info["reason"]  = reason;
-        info["content"] = content;
+        info["status"]  = getStatus();
+        info["reason"]  = getReason();
+        info["content"] = getContent();
         mPumps.obtain(mErrorPump).post(info);
     }
     else                        // default error handling
     {
-        // convention seems to be to use llinfos, but that seems a bit casual?
         LL_WARNS("LLSDMessage::EventResponder")
             << "'" << mMessage << "' to '" << mTarget
-            << "' failed with code " << status << ": " << reason << '\n'
-            << ll_pretty_print_sd(content)
-            << LL_ENDL;
+            << "' failed " << dumpResponse() << LL_ENDL;
     }
 }
 
@@ -151,11 +148,11 @@ bool LLSDMessage::ResponderAdapter::listener(const LLSD& payload, bool success)
 {
     if (success)
     {
-        mResponder->result(payload);
+        mResponder->successResult(payload);
     }
     else
     {
-        mResponder->errorWithContent(payload["status"].asInteger(), payload["reason"], payload["content"]);
+        mResponder->failureResult(payload["status"].asInteger(), payload["reason"], payload["content"]);
     }
 
     /*---------------- MUST BE LAST STATEMENT BEFORE RETURN ----------------*/
diff --git a/indra/llmessage/llsdmessage.h b/indra/llmessage/llsdmessage.h
index 0d34847ff2d75108784659dfcf364620aec04f87..e5d532d6a42c100823a36bd36d617e9e01f894f0 100644
--- a/indra/llmessage/llsdmessage.h
+++ b/indra/llmessage/llsdmessage.h
@@ -123,6 +123,7 @@ class LLSDMessage
     /// LLCapabilityListener. Others should use higher-level APIs.
     class EventResponder: public LLHTTPClient::Responder
     {
+        LOG_CLASS(EventResponder);
     public:
         /**
          * LLHTTPClient::Responder that dispatches via named LLEventPump instances.
@@ -149,8 +150,9 @@ class LLSDMessage
             mErrorPump(errorPump)
         {}
     
-        virtual void result(const LLSD& data);
-        virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
+    protected:
+        virtual void httpSuccess();
+        virtual void httpFailure();
     
     private:
         LLEventPumps& mPumps;
diff --git a/indra/llmessage/llsdrpcclient.h b/indra/llmessage/llsdrpcclient.h
index 0cecf4f68891cde2273abb9ddb5d22f440182cfe..02891d4f32d6879599e7316cf32ad098a7db6422 100644
--- a/indra/llmessage/llsdrpcclient.h
+++ b/indra/llmessage/llsdrpcclient.h
@@ -240,7 +240,7 @@ class LLSDRPCClientFactory : public LLChainIOFactory
 	virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const
 	{
 		lldebugs << "LLSDRPCClientFactory::build" << llendl;
-		LLURLRequest* http(new LLURLRequest(LLURLRequest::HTTP_POST));
+		LLURLRequest* http(new LLURLRequest(HTTP_POST));
 		if(!http->isValid())
 		{
 			llwarns << "Creating LLURLRequest failed." << llendl ;
@@ -251,7 +251,7 @@ class LLSDRPCClientFactory : public LLChainIOFactory
 		LLIOPipe::ptr_t service(new Client);
 		chain.push_back(service);		
 		LLIOPipe::ptr_t http_pipe(http);
-		http->addHeader("Content-Type: text/llsd");
+		http->addHeader(HTTP_HEADER_CONTENT_TYPE, HTTP_CONTENT_TEXT_LLSD);
 		if(mURL.empty())
 		{
 			chain.push_back(LLIOPipe::ptr_t(new LLContextURLExtractor(http)));
@@ -291,7 +291,7 @@ class LLXMLSDRPCClientFactory : public LLChainIOFactory
 	{
 		lldebugs << "LLXMLSDRPCClientFactory::build" << llendl;
 
-		LLURLRequest* http(new LLURLRequest(LLURLRequest::HTTP_POST));
+		LLURLRequest* http(new LLURLRequest(HTTP_POST));
 		if(!http->isValid())
 		{
 			llwarns << "Creating LLURLRequest failed." << llendl ;
@@ -301,7 +301,7 @@ class LLXMLSDRPCClientFactory : public LLChainIOFactory
 		LLIOPipe::ptr_t service(new Client);
 		chain.push_back(service);		
 		LLIOPipe::ptr_t http_pipe(http);
-		http->addHeader("Content-Type: text/xml");
+		http->addHeader(HTTP_HEADER_CONTENT_TYPE, HTTP_CONTENT_TEXT_XML);
 		if(mURL.empty())
 		{
 			chain.push_back(LLIOPipe::ptr_t(new LLContextURLExtractor(http)));
diff --git a/indra/llmessage/lltrustedmessageservice.cpp b/indra/llmessage/lltrustedmessageservice.cpp
index fea7fc72c4903a5ff693f18f43ae7c0e84c848c6..8248b184e9c46102a216806dec12c2c7f3257f00 100644
--- a/indra/llmessage/lltrustedmessageservice.cpp
+++ b/indra/llmessage/lltrustedmessageservice.cpp
@@ -64,7 +64,7 @@ void LLTrustedMessageService::post(LLHTTPNode::ResponsePtr response,
 		LL_WARNS("Messaging") << "trusted message POST to /trusted-message/" 
 				<< name << " from unknown or untrusted sender "
 				<< sender << llendl;
-		response->status(403, "Unknown or untrusted sender");
+		response->status(HTTP_FORBIDDEN, "Unknown or untrusted sender");
 	}
 	else
 	{
diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp
index 627d5918392f94b9d307890d6e225d57dbbbab00..f354f5ab5d8d62c5bd8b9bd0e8c9966ff44fcf3d 100755
--- a/indra/llmessage/llurlrequest.cpp
+++ b/indra/llmessage/llurlrequest.cpp
@@ -40,7 +40,6 @@
 #include "llstring.h"
 #include "apr_env.h"
 #include "llapr.h"
-static const U32 HTTP_STATUS_PIPE_ERROR = 499;
 
 /**
  * String constants
@@ -130,34 +129,15 @@ CURLcode LLURLRequest::_sslCtxCallback(CURL * curl, void *sslctx, void *param)
  * class LLURLRequest
  */
 
-// static
-std::string LLURLRequest::actionAsVerb(LLURLRequest::ERequestAction action)
-{
-	static const std::string VERBS[] =
-	{
-		"(invalid)",
-		"HEAD",
-		"GET",
-		"PUT",
-		"POST",
-		"DELETE",
-		"MOVE"
-	};
-	if(((S32)action <=0) || ((S32)action >= REQUEST_ACTION_COUNT))
-	{
-		return VERBS[0];
-	}
-	return VERBS[action];
-}
 
-LLURLRequest::LLURLRequest(LLURLRequest::ERequestAction action) :
+LLURLRequest::LLURLRequest(EHTTPMethod action) :
 	mAction(action)
 {
 	initialize();
 }
 
 LLURLRequest::LLURLRequest(
-	LLURLRequest::ERequestAction action,
+	EHTTPMethod action,
 	const std::string& url) :
 	mAction(action)
 {
@@ -180,12 +160,17 @@ void LLURLRequest::setURL(const std::string& url)
 	}
 }
 
-std::string LLURLRequest::getURL() const
+const std::string& LLURLRequest::getURL() const
 {
 	return mDetail->mURL;
 }
 
-void LLURLRequest::addHeader(const char* header)
+void LLURLRequest::addHeader(const std::string& header, const std::string& value /* = "" */)
+{
+	mDetail->mCurlRequest->slist_append(header, value);
+}
+
+void LLURLRequest::addHeaderRaw(const char* header)
 {
 	mDetail->mCurlRequest->slist_append(header);
 }
@@ -272,7 +257,7 @@ LLIOPipe::EStatus LLURLRequest::handleError(
 		LLURLRequestComplete* complete = NULL;
 		complete = (LLURLRequestComplete*)mCompletionCallback.get();
 		complete->httpStatus(
-			HTTP_STATUS_PIPE_ERROR,
+			HTTP_INTERNAL_ERROR,
 			LLIOPipe::lookupStatusString(status));
 		complete->responseStatus(status);
 		pump->respond(complete);
@@ -494,7 +479,7 @@ bool LLURLRequest::configure()
 	case HTTP_PUT:
 		// Disable the expect http 1.1 extension. POST and PUT default
 		// to turning this on, and I am not too sure what it means.
-		addHeader("Expect:");
+		addHeader(HTTP_HEADER_EXPECT);
 
 		mDetail->mCurlRequest->setopt(CURLOPT_UPLOAD, 1);
 		mDetail->mCurlRequest->setopt(CURLOPT_INFILESIZE, bytes);
@@ -504,11 +489,11 @@ bool LLURLRequest::configure()
 	case HTTP_POST:
 		// Disable the expect http 1.1 extension. POST and PUT default
 		// to turning this on, and I am not too sure what it means.
-		addHeader("Expect:");
+		addHeader(HTTP_HEADER_EXPECT);
 
 		// Disable the content type http header.
 		// *FIX: what should it be?
-		addHeader("Content-Type:");
+		addHeader(HTTP_HEADER_CONTENT_TYPE);
 
 		// Set the handle for an http post
 		mDetail->mCurlRequest->setPost(NULL, bytes);
@@ -638,7 +623,7 @@ static size_t headerCallback(void* data, size_t size, size_t nmemb, void* user)
 		S32 status_code = atoi(status.c_str());
 		if (status_code > 0)
 		{
-			complete->httpStatus((U32)status_code, reason);
+			complete->httpStatus(status_code, reason);
 			return header_len;
 		}
 	}
diff --git a/indra/llmessage/llurlrequest.h b/indra/llmessage/llurlrequest.h
index 44d358d906f44485af8a193cdc2b092e305c429e..f334c92cc3d3bde22ade7cfec11b428dc4db16f6 100644
--- a/indra/llmessage/llurlrequest.h
+++ b/indra/llmessage/llurlrequest.h
@@ -68,42 +68,22 @@ 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.
-	 */
-	enum ERequestAction
-	{
-		INVALID,
-		HTTP_HEAD,
-		HTTP_GET,
-		HTTP_PUT,
-		HTTP_POST,
-		HTTP_DELETE,
-		HTTP_MOVE, // Caller will need to set 'Destination' header
-		REQUEST_ACTION_COUNT
-	};
-
-	/**
-	 * @brief Turn the requst action into an http verb.
-	 */
-	static std::string actionAsVerb(ERequestAction action);
 
 	/** 
 	 * @brief Constructor.
 	 *
-	 * @param action One of the ERequestAction enumerations.
+	 * @param action One of the EHTTPMethod enumerations.
 	 */
-	LLURLRequest(ERequestAction action);
+	LLURLRequest(EHTTPMethod action);
 
 	/** 
 	 * @brief Constructor.
 	 *
-	 * @param action One of the ERequestAction enumerations.
+	 * @param action One of the EHTTPMethod enumerations.
 	 * @param url The url of the request. It should already be encoded.
 	 */
-	LLURLRequest(ERequestAction action, const std::string& url);
+	LLURLRequest(EHTTPMethod action, const std::string& url);
 
 	/** 
 	 * @brief Destructor.
@@ -123,17 +103,17 @@ class LLURLRequest : public LLIOPipe
 	 * 
 	 */
 	void setURL(const std::string& url);
-	std::string getURL() const;
+	const std::string& getURL() const;
 	/** 
 	 * @brief Add a header to the http post.
 	 *
-	 * The header must be correctly formatted for HTTP requests. This
-	 * provides a raw interface if you know what kind of request you
+	 * This provides a raw interface if you know what kind of request you
 	 * will be making during construction of this instance. All
 	 * required headers will be automatically constructed, so this is
 	 * usually useful for encoding parameters.
 	 */
-	void addHeader(const char* header);
+	void addHeader(const std::string& header, const std::string& value = "");
+	void addHeaderRaw(const char* header);
 
 	/**
 	 * @brief Check remote server certificate signed by a known root CA.
@@ -218,7 +198,7 @@ class LLURLRequest : public LLIOPipe
 		STATE_HAVE_RESPONSE,
 	};
 	EState mState;
-	ERequestAction mAction;
+	EHTTPMethod mAction;
 	LLURLRequestDetail* mDetail;
 	LLIOPipe::ptr_t mCompletionCallback;
 	 S32 mRequestTransferedBytes;
@@ -315,7 +295,7 @@ class LLURLRequestComplete : public LLIOPipe
 	// May be called more than once, particularly for redirects and proxy madness.
 	// Ex. a 200 for a connection to https through a proxy, followed by the "real" status
 	//     a 3xx for a redirect followed by a "real" status, or more redirects.
-	virtual void httpStatus(U32 status, const std::string& reason) { }
+	virtual void httpStatus(S32 status, const std::string& reason) { }
 
 	virtual void complete(
 		const LLChannelDescriptors& channels,
@@ -368,7 +348,7 @@ class LLURLRequestComplete : public LLIOPipe
 	//@}
 
 	// value to note if we actually got the response. This value
-	// depends on correct useage from the LLURLRequest instance.
+	// depends on correct usage from the LLURLRequest instance.
 	EStatus mRequestStatus;
 };
 
diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp
index ae95087377f4fe19197189c6e42c37c14429d536..78b259c3f1081bfa3655a935420422164dd8c9d7 100644
--- a/indra/llmessage/message.cpp
+++ b/indra/llmessage/message.cpp
@@ -113,20 +113,20 @@ namespace
 		{
 		}
 
-		virtual void error(U32 status, const std::string& reason)
+	protected:
+		virtual void httpFailure()
 		{
 			// don't spam when agent communication disconnected already
-			if (status != 410)
+			if (HTTP_GONE != getStatus())
 			{
-				LL_WARNS("Messaging") << "error status " << status
-						<< " for message " << mMessageName
-						<< " reason " << reason << llendl;
+				LL_WARNS("Messaging") << "error for message " << mMessageName
+					<< " " << dumpResponse() << LL_ENDL;
 			}
 			// TODO: Map status in to useful error code.
 			if(NULL != mCallback) mCallback(mCallbackData, LL_ERR_TCP_TIMEOUT);
 		}
 		
-		virtual void result(const LLSD& content)
+		virtual void httpSuccess()
 		{
 			if(NULL != mCallback) mCallback(mCallbackData, LL_ERR_NOERR);
 		}
diff --git a/indra/llmessage/tests/llcurl_stub.cpp b/indra/llmessage/tests/llcurl_stub.cpp
index 9b298d0c049ef5177018393c3d200d3ea2e51957..b7fdf4f437b075ae07977d1bc107a05e6d32e5f9 100644
--- a/indra/llmessage/tests/llcurl_stub.cpp
+++ b/indra/llmessage/tests/llcurl_stub.cpp
@@ -24,55 +24,76 @@
  * $/LicenseInfo$
  */
 
+#ifndef LL_CURL_STUB_CPP
+#define LL_CURL_STUB_CPP
+
+
 #include "linden_common.h"
 #include "llcurl.h"
+#include "llhttpconstants.cpp"
 
 LLCurl::Responder::Responder()
 {
 }
 
-void LLCurl::Responder::completed(U32 status, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const &reason,
-								  LLSD const& mContent)
+void LLCurl::Responder::httpCompleted()
 {
-	if (isGoodStatus(status))
+	if (isGoodStatus())
 	{
-		result(mContent);
+		httpSuccess();
 	}
 	else
 	{
-		errorWithContent(status, reason, mContent);
+		httpFailure();
 	}
 }
 
-void LLCurl::Responder::completedHeader(unsigned,
-										std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&,
-										LLSD const&)
+void LLCurl::Responder::completedRaw(LLChannelDescriptors const&,
+									 boost::shared_ptr<LLBufferArray> const&)
 {
 }
 
-void LLCurl::Responder::completedRaw(unsigned,
-									 std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&,
-									 LLChannelDescriptors const&,
-									 boost::shared_ptr<LLBufferArray> const&)
+void LLCurl::Responder::httpFailure()
 {
 }
 
-void LLCurl::Responder::errorWithContent(unsigned,
-							  std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&,
-							  LLSD const&)
+LLCurl::Responder::~Responder ()
 {
 }
 
-LLCurl::Responder::~Responder ()
+void LLCurl::Responder::httpSuccess()
+{
+}
+
+std::string LLCurl::Responder::dumpResponse() const
+{
+	return "dumpResponse()";
+}
+
+void LLCurl::Responder::successResult(const LLSD& content)
 {
+	setResult(HTTP_OK, "", content);
+	httpSuccess();
 }
 
-void LLCurl::Responder::error(unsigned,
-							  std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
+void LLCurl::Responder::failureResult(S32 status, const std::string& reason, const LLSD& content)
+{
+	setResult(status, reason, content);
+	httpFailure();
+}
+
+
+void LLCurl::Responder::completeResult(S32 status, const std::string& reason, const LLSD& content)
 {
+	setResult(status, reason, content);
+	httpCompleted();
 }
 
-void LLCurl::Responder::result(LLSD const&)
+void LLCurl::Responder::setResult(S32 status, const std::string& reason, const LLSD& content /* = LLSD() */)
 {
+	mStatus = status;
+	mReason = reason;
+	mContent = content;
 }
 
+#endif
diff --git a/indra/llmessage/tests/llhttpclient_test.cpp b/indra/llmessage/tests/llhttpclient_test.cpp
index 87cbafa404c441e83a481e0302fbfe021c7096bf..bdc48ce53dbeaf283a43aaed3a74ec1a8c96c431 100644
--- a/indra/llmessage/tests/llhttpclient_test.cpp
+++ b/indra/llmessage/tests/llhttpclient_test.cpp
@@ -101,7 +101,7 @@ namespace tut
 			if (mSawError)
 			{
 				std::string msg =
-					llformat("error() called when not expected, status %d",
+					llformat("httpFailure() called when not expected, status %d",
 						mStatus);
 				fail(msg);
 			}
@@ -111,7 +111,7 @@ namespace tut
 		{
 			if (!mSawError)
 			{
-				fail("error() wasn't called");
+				fail("httpFailure() wasn't called");
 			}
 		}
 
@@ -153,33 +153,26 @@ namespace tut
 				mClient.mResultDeleted = true;
 			}
 
-			virtual void error(U32 status, const std::string& reason)
+		protected:
+			virtual void httpFailure()
 			{
 				mClient.mSawError = true;
-				mClient.mStatus = status;
-				mClient.mReason = reason;
+				mClient.mStatus = getStatus();
+				mClient.mReason = getReason();
 			}
 
-			virtual void result(const LLSD& content)
+			virtual void httpSuccess()
 			{
-				mClient.mResult = content;
+				mClient.mResult = getContent();
 			}
 
-			virtual void completed(
-							U32 status, const std::string& reason,
-							const LLSD& content)
+			virtual void httpCompleted()
 			{
-				LLHTTPClient::Responder::completed(status, reason, content);
-
+				LLHTTPClient::Responder::httpCompleted();
+				
 				mClient.mSawCompleted = true;
-			}
-
-			virtual void completedHeader(
-				U32 status, const std::string& reason,
-				const LLSD& content)
-			{
-				mClient.mHeader = content;
 				mClient.mSawCompletedHeader = true;
+				mClient.mHeader = getResponseHeaders();
 			}
 
 		private:
diff --git a/indra/llmessage/tests/llhttpclientadapter_test.cpp b/indra/llmessage/tests/llhttpclientadapter_test.cpp
index 13ce0a0edd85638f296da15b021636d145010c96..cc7feeab4f1a143c3d9ff3678a8ac6276efe04bd 100644
--- a/indra/llmessage/tests/llhttpclientadapter_test.cpp
+++ b/indra/llmessage/tests/llhttpclientadapter_test.cpp
@@ -1,6 +1,6 @@
 /** 
- * @file 
- * @brief 
+ * @file llhttpclientadapter_test.cpp
+ * @brief Tests for LLHTTPClientAdapter
  *
  * $LicenseInfo:firstyear=2008&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -33,8 +33,8 @@
 float const HTTP_REQUEST_EXPIRY_SECS = 1.0F;
 
 std::vector<std::string> get_urls;
-std::vector<boost::intrusive_ptr<LLCurl::Responder> > get_responders;
-void LLHTTPClient::get(const std::string& url, boost::intrusive_ptr<LLCurl::Responder> responder, const LLSD& headers, const F32 timeout)
+std::vector< LLCurl::ResponderPtr > get_responders;
+void LLHTTPClient::get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers, const F32 timeout)
 {
 	get_urls.push_back(url);
 	get_responders.push_back(responder);
@@ -42,16 +42,30 @@ void LLHTTPClient::get(const std::string& url, boost::intrusive_ptr<LLCurl::Resp
 
 std::vector<std::string> put_urls;
 std::vector<LLSD> put_body;
-std::vector<boost::intrusive_ptr<LLCurl::Responder> > put_responders;
+std::vector<LLSD> put_headers;
+std::vector<LLCurl::ResponderPtr> put_responders;
 
-void LLHTTPClient::put(const std::string& url, const LLSD& body, boost::intrusive_ptr<LLCurl::Responder> responder, const LLSD& headers, const F32 timeout)
+void LLHTTPClient::put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder, const LLSD& headers, const F32 timeout)
 {
 	put_urls.push_back(url);
 	put_responders.push_back(responder);
 	put_body.push_back(body);
+	put_headers.push_back(headers);
 
 }
 
+std::vector<std::string> delete_urls;
+std::vector<LLCurl::ResponderPtr> delete_responders;
+
+void LLHTTPClient::del(
+	const std::string& url,
+	LLCurl::ResponderPtr responder,
+	const LLSD& headers,
+	const F32 timeout)
+{
+	delete_urls.push_back(url);
+	delete_responders.push_back(responder);
+}
 
 namespace tut
 {
@@ -64,6 +78,9 @@ namespace tut
 			put_urls.clear();
 			put_responders.clear();
 			put_body.clear();
+			put_headers.clear();
+			delete_urls.clear();
+			delete_responders.clear();
 		}
 	};
 
@@ -73,7 +90,7 @@ namespace tut
 
 namespace
 {
-	tut::factory tf("LLHTTPClientAdapterData test");
+	tut::factory tf("LLHTTPClientAdapterData");
 }
 
 namespace tut
@@ -91,7 +108,7 @@ namespace tut
 	{
 		LLHTTPClientAdapter adapter;
 
-		boost::intrusive_ptr<LLCurl::Responder> responder = new LLCurl::Responder();
+		LLCurl::ResponderPtr responder = new LLCurl::Responder();
 
 		adapter.get("Made up URL", responder);
 		ensure_equals(get_urls.size(), 1);
@@ -103,7 +120,7 @@ namespace tut
 	void object::test<3>()
 	{
 		LLHTTPClientAdapter adapter;
-		boost::intrusive_ptr<LLCurl::Responder> responder = new LLCurl::Responder();
+		LLCurl::ResponderPtr responder = new LLCurl::Responder();
 
 		adapter.get("Made up URL", responder);
 
@@ -117,7 +134,7 @@ namespace tut
 	{
 		LLHTTPClientAdapter adapter;
 
-		boost::intrusive_ptr<LLCurl::Responder> responder = new LLCurl::Responder();
+		LLCurl::ResponderPtr responder = new LLCurl::Responder();
 
 		LLSD body;
 		body["TestBody"] = "Foobar";
@@ -133,7 +150,7 @@ namespace tut
 	{
 		LLHTTPClientAdapter adapter;
 
-		boost::intrusive_ptr<LLCurl::Responder> responder = new LLCurl::Responder();
+		LLCurl::ResponderPtr responder = new LLCurl::Responder();
 
 		LLSD body;
 		body["TestBody"] = "Foobar";
@@ -150,7 +167,7 @@ namespace tut
 	{
 		LLHTTPClientAdapter adapter;
 
-		boost::intrusive_ptr<LLCurl::Responder> responder = new LLCurl::Responder();
+		LLCurl::ResponderPtr responder = new LLCurl::Responder();
 
 		LLSD body;
 		body["TestBody"] = "Foobar";
@@ -160,5 +177,45 @@ namespace tut
 		ensure_equals(put_body.size(), 1);
 		ensure_equals(put_body[0]["TestBody"].asString(), "Foobar");
 	}
+
+	// Ensure that headers are passed through put properly
+	template<> template<>
+	void object::test<7>()
+	{
+		LLHTTPClientAdapter adapter;
+
+		LLCurl::ResponderPtr responder = new LLCurl::Responder();
+
+		LLSD body = LLSD::emptyMap();
+		body["TestBody"] = "Foobar";
+
+		LLSD headers = LLSD::emptyMap();
+		headers["booger"] = "omg";
+
+		adapter.put("Made up URL", body, responder, headers);
+
+		ensure_equals("Header count", put_headers.size(), 1);
+		ensure_equals(
+			"First header",
+			put_headers[0]["booger"].asString(),
+			"omg");
+	}
+
+	// Ensure that del() passes appropriate arguments to the LLHTTPClient
+	template<> template<>
+	void object::test<8>()
+	{
+		LLHTTPClientAdapter adapter;
+
+		LLCurl::ResponderPtr responder = new LLCurl::Responder();
+
+		adapter.del("Made up URL", responder);
+
+		ensure_equals("URL count", delete_urls.size(), 1);
+		ensure_equals("Received URL", delete_urls[0], "Made up URL");
+
+		ensure_equals("Responder count", delete_responders.size(), 1);
+		//ensure_equals("Responder", delete_responders[0], responder);
+	}
 }
 
diff --git a/indra/llmessage/tests/llmime_test.cpp b/indra/llmessage/tests/llmime_test.cpp
index aed5c4589cba1d567635351c7ed0ff77008924df..f8bf03bbcb36aa9436a08a58241c0906277c3c22 100644
--- a/indra/llmessage/tests/llmime_test.cpp
+++ b/indra/llmessage/tests/llmime_test.cpp
@@ -29,6 +29,7 @@
 #include "linden_common.h"
 
 #include "llsdserialize.h"
+#include "llhttpconstants.cpp"
 
 #include "../llmime.h"
 
diff --git a/indra/llmessage/tests/llregionpresenceverifier_test.cpp b/indra/llmessage/tests/llregionpresenceverifier_test.cpp
deleted file mode 100644
index 5b89f2a8c672d2a089d59497c4c9a2981aa9ca79..0000000000000000000000000000000000000000
--- a/indra/llmessage/tests/llregionpresenceverifier_test.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/** 
- * @file 
- * @brief 
- *
- * $LicenseInfo:firstyear=2008&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "linden_common.h"
-
-#include "../test/lltut.h"
-#include "llregionpresenceverifier.h"
-#include "llcurl_stub.cpp"
-#include "llhost.cpp"
-#include "net.cpp"
-#include "lltesthttpclientadapter.cpp"
-
-class LLTestResponse : public LLRegionPresenceVerifier::Response
-{
-public:
-
-	virtual bool checkValidity(const LLSD& content) const
-	{
-		return true;
-	}
-
-	virtual void onRegionVerified(const LLSD& region_details)
-	{
-	}
-
-	virtual void onRegionVerificationFailed()
-	{
-	}
-	
-	virtual LLHTTPClientInterface& getHttpClient()
-	{
-		return mHttpInterface;
-	}
-
-	LLTestHTTPClientAdapter mHttpInterface;
-};
-
-namespace tut
-{
-	struct LLRegionPresenceVerifierData
-	{
-		LLRegionPresenceVerifierData() :
-			mResponse(new LLTestResponse()),
-			mResponder("", LLRegionPresenceVerifier::ResponsePtr(mResponse),
-					   LLSD(), 3)
-		{
-		}
-		
-		LLTestResponse* mResponse;
-		LLRegionPresenceVerifier::VerifiedDestinationResponder mResponder;
-	};
-
-	typedef test_group<LLRegionPresenceVerifierData> factory;
-	typedef factory::object object;
-}
-
-namespace
-{
-	tut::factory tf("LLRegionPresenceVerifier");
-}
-
-namespace tut
-{
-	// Test that VerifiedDestinationResponder does retry
-    // on error when shouldRetry returns true.
-	template<> template<>
-	void object::test<1>()
-	{
-		mResponder.error(500, "Internal server error");
-		ensure_equals(mResponse->mHttpInterface.mGetUrl.size(), 1);
-	}
-
-	// Test that VerifiedDestinationResponder only retries
-	// on error until shouldRetry returns false.
-	template<> template<>
-	void object::test<2>()
-	{
-		mResponder.error(500, "Internal server error");
-		mResponder.error(500, "Internal server error");
-		mResponder.error(500, "Internal server error");
-		mResponder.error(500, "Internal server error");
-		ensure_equals(mResponse->mHttpInterface.mGetUrl.size(), 3);
-	}
-}
-
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index baedac1f2dba0a81ae9359e412fceb67c8590d01..eb41c0aa3aaba06bb4d6237e2f141593ec4a44a8 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -2068,10 +2068,21 @@ if (LL_TESTS)
     #llviewertexturelist.cpp
   )
 
+  set(test_libs
+    ${JSONCPP_LIBRARIES}
+    ${CURL_LIBRARIES}
+    )
+
   set_source_files_properties(
     lltranslate.cpp
     PROPERTIES
-    LL_TEST_ADDITIONAL_LIBRARIES "${JSONCPP_LIBRARIES}"
+    LL_TEST_ADDITIONAL_LIBRARIES "${test_libs}"
+  )
+
+  set_source_files_properties(
+    llmediadataclient.cpp
+    PROPERTIES
+    LL_TEST_ADDITIONAL_LIBRARIES "${CURL_LIBRARIES}"
   )
 
   set_source_files_properties(
diff --git a/indra/newview/llaccountingcostmanager.cpp b/indra/newview/llaccountingcostmanager.cpp
index 7662a9689daa0849a6a22146c722bb27dc48a9de..55d453cdcceb784f4e136de12f5702281dc2038d 100644
--- a/indra/newview/llaccountingcostmanager.cpp
+++ b/indra/newview/llaccountingcostmanager.cpp
@@ -36,6 +36,7 @@ LLAccountingCostManager::LLAccountingCostManager()
 //===============================================================================
 class LLAccountingCostResponder : public LLCurl::Responder
 {
+	LOG_CLASS(LLAccountingCostResponder);
 public:
 	LLAccountingCostResponder( const LLSD& objectIDs, const LLHandle<LLAccountingCostObserver>& observer_handle )
 	: mObjectIDs( objectIDs ),
@@ -56,24 +57,27 @@ class LLAccountingCostResponder : public LLCurl::Responder
 		}
 	}
 	
-	void errorWithContent( U32 statusNum, const std::string& reason, const LLSD& content )
+protected:
+	void httpFailure()
 	{
-		llwarns << "Transport error [status:" << statusNum << "]: " << content <<llendl;
+		llwarns << dumpResponse() << llendl;
 		clearPendingRequests();
 
 		LLAccountingCostObserver* observer = mObserverHandle.get();
 		if (observer && observer->getTransactionID() == mTransactionID)
 		{
-			observer->setErrorStatus(statusNum, reason);
+			observer->setErrorStatus(getStatus(), getReason());
 		}
 	}
 	
-	void result( const LLSD& content )
+	void httpSuccess()
 	{
+		const LLSD& content = getContent();
 		//Check for error
 		if ( !content.isMap() || content.has("error") )
 		{
-			llwarns	<< "Error on fetched data"<< llendl;
+			failureResult(HTTP_INTERNAL_ERROR, "Error on fetched data", content);
+			return;
 		}
 		else if (content.has("selected"))
 		{
diff --git a/indra/newview/llaccountingcostmanager.h b/indra/newview/llaccountingcostmanager.h
index 0bca1f54ef76a7b078c72d63dd5405bdb27c0bba..3ade34c81d0a6c7a1be2faa010e7ffd06df4427c 100644
--- a/indra/newview/llaccountingcostmanager.h
+++ b/indra/newview/llaccountingcostmanager.h
@@ -38,7 +38,7 @@ class LLAccountingCostObserver
 	LLAccountingCostObserver() { mObserverHandle.bind(this); }
 	virtual ~LLAccountingCostObserver() {}
 	virtual void onWeightsUpdate(const SelectionCost& selection_cost) = 0;
-	virtual void setErrorStatus(U32 status, const std::string& reason) = 0;
+	virtual void setErrorStatus(S32 status, const std::string& reason) = 0;
 	const LLHandle<LLAccountingCostObserver>& getObserverHandle() const { return mObserverHandle; }
 	const LLUUID& getTransactionID() { return mTransactionID; }
 
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 20954e4baefd9d8e715d2651c76830de609641b5..4b0f4510361301f647a03319818caaf3ad83ff5a 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -2546,17 +2546,19 @@ int LLAgent::convertTextToMaturity(char text)
 
 class LLMaturityPreferencesResponder : public LLHTTPClient::Responder
 {
+	LOG_CLASS(LLMaturityPreferencesResponder);
 public:
 	LLMaturityPreferencesResponder(LLAgent *pAgent, U8 pPreferredMaturity, U8 pPreviousMaturity);
 	virtual ~LLMaturityPreferencesResponder();
 
-	virtual void result(const LLSD &pContent);
-	virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);
+protected:
+	virtual void httpSuccess();
+	virtual void httpFailure();
 
 protected:
 
 private:
-	U8 parseMaturityFromServerResponse(const LLSD &pContent);
+	U8 parseMaturityFromServerResponse(const LLSD &pContent) const;
 
 	LLAgent                                  *mAgent;
 	U8                                       mPreferredMaturity;
@@ -2575,29 +2577,33 @@ LLMaturityPreferencesResponder::~LLMaturityPreferencesResponder()
 {
 }
 
-void LLMaturityPreferencesResponder::result(const LLSD &pContent)
+void LLMaturityPreferencesResponder::httpSuccess()
 {
-	U8 actualMaturity = parseMaturityFromServerResponse(pContent);
+	U8 actualMaturity = parseMaturityFromServerResponse(getContent());
 
 	if (actualMaturity != mPreferredMaturity)
 	{
-		llwarns << "while attempting to change maturity preference from '" << LLViewerRegion::accessToString(mPreviousMaturity)
-			<< "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) << "', the server responded with '"
-			<< LLViewerRegion::accessToString(actualMaturity) << "' [value:" << static_cast<U32>(actualMaturity) << ", llsd:"
-			<< pContent << "]" << llendl;
+		llwarns << "while attempting to change maturity preference from '"
+				<< LLViewerRegion::accessToString(mPreviousMaturity)
+				<< "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) 
+				<< "', the server responded with '"
+				<< LLViewerRegion::accessToString(actualMaturity) 
+				<< "' [value:" << static_cast<U32>(actualMaturity) 
+				<< "], " << dumpResponse() << llendl;
 	}
 	mAgent->handlePreferredMaturityResult(actualMaturity);
 }
 
-void LLMaturityPreferencesResponder::errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent)
+void LLMaturityPreferencesResponder::httpFailure()
 {
-	llwarns << "while attempting to change maturity preference from '" << LLViewerRegion::accessToString(mPreviousMaturity)
-		<< "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) << "', we got an error with [status:"
-		<< pStatus << "]: " << (pContent.isDefined() ? pContent : LLSD(pReason)) << llendl;
+	llwarns << "while attempting to change maturity preference from '" 
+			<< LLViewerRegion::accessToString(mPreviousMaturity)
+			<< "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) 
+			<< "', " << dumpResponse() << llendl;
 	mAgent->handlePreferredMaturityError();
 }
 
-U8 LLMaturityPreferencesResponder::parseMaturityFromServerResponse(const LLSD &pContent)
+U8 LLMaturityPreferencesResponder::parseMaturityFromServerResponse(const LLSD &pContent) const
 {
 	// stinson 05/24/2012 Pathfinding regions have re-defined the response behavior.  In the old server code,
 	// if you attempted to change the preferred maturity to the same value, the response content would be an
@@ -2605,7 +2611,7 @@ U8 LLMaturityPreferencesResponder::parseMaturityFromServerResponse(const LLSD &p
 	// defined.  Thus, the check for isUndefined() can be replaced with an assert after pathfinding is merged
 	// into server trunk and fully deployed.
 	U8 maturity = SIM_ACCESS_MIN;
-	if (pContent.isUndefined())
+	if (pContent.isUndefined() || !pContent.isMap())
 	{
 		maturity = mPreferredMaturity;
 	}
@@ -2783,7 +2789,7 @@ void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity)
 		// If we don't have a region, report it as an error
 		if (getRegion() == NULL)
 		{
-			responderPtr->errorWithContent(0U, "region is not defined", LLSD());
+			responderPtr->failureResult(0U, "region is not defined", LLSD());
 		}
 		else
 		{
@@ -2793,7 +2799,7 @@ void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity)
 			// If the capability is not defined, report it as an error
 			if (url.empty())
 			{
-				responderPtr->errorWithContent(0U, 
+				responderPtr->failureResult(0U, 
 							"capability 'UpdateAgentInformation' is not defined for region", LLSD());
 			}
 			else
@@ -3292,8 +3298,7 @@ class LLAgentDropGroupViewerNode : public LLHTTPNode
 			!input.has("body") )
 		{
 			//what to do with badly formed message?
-			response->statusUnknownError(400);
-			response->result(LLSD("Invalid message parameters"));
+			response->extendedResult(HTTP_BAD_REQUEST, LLSD("Invalid message parameters"));
 		}
 
 		LLSD body = input["body"];
@@ -3362,8 +3367,7 @@ class LLAgentDropGroupViewerNode : public LLHTTPNode
 		else
 		{
 			//what to do with badly formed message?
-			response->statusUnknownError(400);
-			response->result(LLSD("Invalid message parameters"));
+			response->extendedResult(HTTP_BAD_REQUEST, LLSD("Invalid message parameters"));
 		}
 	}
 };
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 2c76efc7fb8b62e76e4550c51b58e78271282c6c..92a896a3c277e776d3df3e6c54fd4395fcb13135 100755
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -2984,20 +2984,23 @@ class LLHTTPRetryPolicy: public LLThreadSafeRefCount
 public:
 	LLHTTPRetryPolicy() {}
 	virtual ~LLHTTPRetryPolicy() {}
-	virtual bool shouldRetry(U32 status, F32& seconds_to_wait) = 0;
+	virtual bool shouldRetry(S32 status, const LLSD& headers, F32& seconds_to_wait) = 0;
 };
 
 // Example of simplest possible policy, not necessarily recommended.
+// This would be a potentially dangerous policy to enable.  Removing for now:
+#if 0
 class LLAlwaysRetryImmediatelyPolicy: public LLHTTPRetryPolicy
 {
 public:
 	LLAlwaysRetryImmediatelyPolicy() {}
-	bool shouldRetry(U32 status, F32& seconds_to_wait)
+	bool shouldRetry(S32 status, const LLSD& headers, F32& seconds_to_wait)
 	{
 		seconds_to_wait = 0.0;
 		return true;
 	}
 };
+#endif
 
 // Very general policy with geometric back-off after failures,
 // up to a maximum delay, and maximum number of retries.
@@ -3014,10 +3017,25 @@ class LLAdaptiveRetryPolicy: public LLHTTPRetryPolicy
 	{
 	}
 
-	bool shouldRetry(U32 status, F32& seconds_to_wait)
+	bool shouldRetry(S32 status, const LLSD& headers, F32& seconds_to_wait)
 	{
-		seconds_to_wait = mDelay;
-		mDelay = llclamp(mDelay*mBackoffFactor,mMinDelay,mMaxDelay);
+#if 0
+		// *TODO: Test using status codes to only retry server errors.
+		// Only server errors would potentially return a different result on retry.
+		if (!isHttpServerErrorStatus(status)) return false;
+#endif
+
+#if 0
+		// *TODO: Honor server Retry-After header.
+		// Status 503 may ask us to wait for a certain amount of time before retrying.
+		if (!headers.has(HTTP_HEADER_RETRY_AFTER)
+			|| !getSecondsUntilRetryAfter(headers[HTTP_HEADER_RETRY_AFTER].asStringRef(), seconds_to_wait))
+#endif
+		{
+			seconds_to_wait = mDelay;
+			mDelay = llclamp(mDelay*mBackoffFactor,mMinDelay,mMaxDelay);
+		}
+
 		mRetryCount++;
 		return (mRetryCount<=mMaxRetries);
 	}
@@ -3033,6 +3051,7 @@ class LLAdaptiveRetryPolicy: public LLHTTPRetryPolicy
 
 class RequestAgentUpdateAppearanceResponder: public LLHTTPClient::Responder
 {
+	LOG_CLASS(RequestAgentUpdateAppearanceResponder);
 public:
 	RequestAgentUpdateAppearanceResponder()
 	{
@@ -3043,13 +3062,19 @@ class RequestAgentUpdateAppearanceResponder: public LLHTTPClient::Responder
 	{
 	}
 
+protected:
 	// Successful completion.
-	/* virtual */ void result(const LLSD& content)
+	/* virtual */ void httpSuccess()
 	{
-		LL_DEBUGS("Avatar") << "content: " << ll_pretty_print_sd(content) << LL_ENDL;
+		const LLSD& content = getContent();
+		if (!content.isMap())
+		{
+			failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+			return;
+		}
 		if (content["success"].asBoolean())
 		{
-			LL_DEBUGS("Avatar") << "OK" << LL_ENDL;
+			LL_DEBUGS("Avatar") << dumpResponse() << LL_ENDL;
 			if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
 			{
 				dumpContents(gAgentAvatarp->getFullname() + "_appearance_request_ok", content);
@@ -3057,33 +3082,35 @@ class RequestAgentUpdateAppearanceResponder: public LLHTTPClient::Responder
 		}
 		else
 		{
-			onFailure(200);
+			failureResult(HTTP_INTERNAL_ERROR, "Non-success response", content);
 		}
 	}
 
 	// Error
-	/*virtual*/ void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+	/*virtual*/ void httpFailure()
 	{
-		llwarns << "appearance update request failed, status: " << status << " reason: " << reason << " code: " << content["code"].asInteger() << " error: \"" << content["error"].asString() << "\"" << llendl;
+		const LLSD& content = getContent();
+		LL_WARNS("Avatar") << "appearance update request failed "
+				<< dumpResponse() << LL_ENDL;
 		if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
 		{
 			dumpContents(gAgentAvatarp->getFullname() + "_appearance_request_error", content);
 			debugCOF(content);
 		
 		}
-		onFailure(status);
-	}	
+		onFailure();
+	}
 
-	void onFailure(U32 status)
+	void onFailure()
 	{
 		F32 seconds_to_wait;
-		if (mRetryPolicy->shouldRetry(status,seconds_to_wait))
+		if (mRetryPolicy->shouldRetry(getStatus(), getResponseHeaders(), seconds_to_wait))
 		{
 			llinfos << "retrying" << llendl;
 			doAfterInterval(boost::bind(&LLAppearanceMgr::requestServerAppearanceUpdate,
 										LLAppearanceMgr::getInstance(),
-										LLCurl::ResponderPtr(this)),
-							seconds_to_wait);
+										LLHTTPClient::ResponderPtr(this)),
+										seconds_to_wait);
 		}
 		else
 		{
@@ -3286,6 +3313,7 @@ void LLAppearanceMgr::requestServerAppearanceUpdate(LLCurl::ResponderPtr respond
 
 class LLIncrementCofVersionResponder : public LLHTTPClient::Responder
 {
+	LOG_CLASS(LLIncrementCofVersionResponder);
 public:
 	LLIncrementCofVersionResponder() : LLHTTPClient::Responder()
 	{
@@ -3296,10 +3324,17 @@ class LLIncrementCofVersionResponder : public LLHTTPClient::Responder
 	{
 	}
 
-	virtual void result(const LLSD &pContent)
+protected:
+	virtual void httpSuccess()
 	{
 		llinfos << "Successfully incremented agent's COF." << llendl;
-		S32 new_version = pContent["category"]["version"].asInteger();
+		const LLSD& content = getContent();
+		if (!content.isMap())
+		{
+			failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+			return;
+		}
+		S32 new_version = content["category"]["version"].asInteger();
 
 		LLAppearanceMgr* app_mgr = LLAppearanceMgr::getInstance();
 
@@ -3308,12 +3343,13 @@ class LLIncrementCofVersionResponder : public LLHTTPClient::Responder
 
 		app_mgr->mLastUpdateRequestCOFVersion = new_version;
 	}
-	virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& content)
+
+	virtual void httpFailure()
 	{
-		llwarns << "While attempting to increment the agent's cof we got an error with [status:"
-				<< pStatus << "]: " << content << llendl;
+		LL_WARNS("Avatar") << "While attempting to increment the agent's cof we got an error "
+				<< dumpResponse() << LL_ENDL;
 		F32 seconds_to_wait;
-		if (mRetryPolicy->shouldRetry(pStatus,seconds_to_wait))
+		if (mRetryPolicy->shouldRetry(getStatus(), getResponseHeaders(), seconds_to_wait))
 		{
 			llinfos << "retrying" << llendl;
 			doAfterInterval(boost::bind(&LLAppearanceMgr::incrementCofVersion,
@@ -3327,6 +3363,7 @@ class LLIncrementCofVersionResponder : public LLHTTPClient::Responder
 		}
 	}
 
+private:
 	LLPointer<LLHTTPRetryPolicy> mRetryPolicy;
 };
 
diff --git a/indra/newview/llassetuploadqueue.cpp b/indra/newview/llassetuploadqueue.cpp
index 4bdb690225d6b871876ceb0e5a33de65fcf81086..cde9bc9dc08b77a3deb52da853afabd32c702584 100644
--- a/indra/newview/llassetuploadqueue.cpp
+++ b/indra/newview/llassetuploadqueue.cpp
@@ -36,6 +36,7 @@
 
 class LLAssetUploadChainResponder : public LLUpdateTaskInventoryResponder
 {
+	LOG_CLASS(LLAssetUploadChainResponder);
 public:
 	
 	LLAssetUploadChainResponder(const LLSD& post_data,
@@ -51,52 +52,54 @@ class LLAssetUploadChainResponder : public LLUpdateTaskInventoryResponder
 		mDataSize(data_size),
 		mScriptName(script_name)
 	{
- 	}
+	}
 
 	virtual ~LLAssetUploadChainResponder() 
-   	{
-   		if(mSupplier)
-   		{
-   			LLAssetUploadQueue *queue = mSupplier->get();
-   			if (queue)
-   			{
-   				// Give ownership of supplier back to queue.
-   				queue->mSupplier = mSupplier;
-   				mSupplier = NULL;
-   			}
-   		}
-   		delete mSupplier;
+	{
+		if(mSupplier)
+		{
+			LLAssetUploadQueue *queue = mSupplier->get();
+			if (queue)
+			{
+				// Give ownership of supplier back to queue.
+				queue->mSupplier = mSupplier;
+				mSupplier = NULL;
+			}
+		}
+		delete mSupplier;
 		delete mData;
-   	}
+	}
 	
-	virtual void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
-   	{
-		llwarns << "LLAssetUploadChainResponder Error [status:" 
-				<< statusNum << "]: " << content << llendl;
-		LLUpdateTaskInventoryResponder::errorWithContent(statusNum, reason, content);
-   		LLAssetUploadQueue *queue = mSupplier->get();
-   		if (queue)
+protected:
+	virtual void httpFailure()
+	{
+		// Parent class will spam the failure.
+		//llwarns << dumpResponse() << llendl;
+		LLUpdateTaskInventoryResponder::httpFailure();
+		LLAssetUploadQueue *queue = mSupplier->get();
+		if (queue)
+		{
+			queue->request(&mSupplier);
+		}
+	}
+
+	virtual void httpSuccess()
+	{
+		LLUpdateTaskInventoryResponder::httpSuccess();
+		LLAssetUploadQueue *queue = mSupplier->get();
+		if (queue)
 		{
-   			queue->request(&mSupplier);
-   		}
-   	}
-
-	virtual void result(const LLSD& content)
-   	{
-		LLUpdateTaskInventoryResponder::result(content);
-   		LLAssetUploadQueue *queue = mSupplier->get();
-   		if (queue)
-   		{
-   			// Responder is reused across 2 phase upload,
-   			// so only start next upload after 2nd phase complete.
-   			std::string state = content["state"];
-   			if(state == "complete")
-   			{
-   				queue->request(&mSupplier);
-   			}
-   		}	
-   	}
+			// Responder is reused across 2 phase upload,
+			// so only start next upload after 2nd phase complete.
+			const std::string& state = getContent()["state"].asStringRef();
+			if(state == "complete")
+			{
+				queue->request(&mSupplier);
+			}
+		}
+	}
 	
+public:
 	virtual void uploadUpload(const LLSD& content)
 	{
 		std::string uploader = content["uploader"];
diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp
index 25648023879a9ee2e99ddd17f04df74292e4fcd7..ea511b18e2de5d8dfb74619018e9206778c8eb48 100644
--- a/indra/newview/llassetuploadresponders.cpp
+++ b/indra/newview/llassetuploadresponders.cpp
@@ -225,37 +225,41 @@ LLAssetUploadResponder::~LLAssetUploadResponder()
 }
 
 // virtual
-void LLAssetUploadResponder::errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
+void LLAssetUploadResponder::httpFailure()
 {
-	llinfos << "LLAssetUploadResponder::error [status:" 
-			<< statusNum << "]: " << content << llendl;
+	// *TODO: Add adaptive retry policy?
+	llwarns << dumpResponse() << llendl;
 	LLSD args;
-	switch(statusNum)
+	if (isHttpClientErrorStatus(getStatus()))
 	{
-		case 400:
-			args["FILE"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
-			args["REASON"] = "Error in upload request.  Please visit "
-				"http://secondlife.com/support for help fixing this problem.";
-			LLNotificationsUtil::add("CannotUploadReason", args);
-			break;
-		case 500:
-		default:
-			args["FILE"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
-			args["REASON"] = "The server is experiencing unexpected "
-				"difficulties.";
-			LLNotificationsUtil::add("CannotUploadReason", args);
-			break;
+		args["FILE"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
+		args["REASON"] = "Error in upload request.  Please visit "
+			"http://secondlife.com/support for help fixing this problem.";
+		LLNotificationsUtil::add("CannotUploadReason", args);
+	}
+	else
+	{
+		args["FILE"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
+		args["REASON"] = "The server is experiencing unexpected "
+			"difficulties.";
+		LLNotificationsUtil::add("CannotUploadReason", args);
 	}
 	LLUploadDialog::modalUploadFinished();
 	LLFilePicker::instance().reset();  // unlock file picker when bulk upload fails
 }
 
 //virtual 
-void LLAssetUploadResponder::result(const LLSD& content)
+void LLAssetUploadResponder::httpSuccess()
 {
+	const LLSD& content = getContent();
+	if (!content.isMap())
+	{
+		failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+		return;
+	}
 	lldebugs << "LLAssetUploadResponder::result from capabilities" << llendl;
 
-	std::string state = content["state"];
+	const std::string& state = content["state"].asStringRef();
 
 	if (state == "upload")
 	{
@@ -280,7 +284,7 @@ void LLAssetUploadResponder::result(const LLSD& content)
 
 void LLAssetUploadResponder::uploadUpload(const LLSD& content)
 {
-	std::string uploader = content["uploader"];
+	const std::string& uploader = content["uploader"].asStringRef();
 	if (mFileName.empty())
 	{
 		LLHTTPClient::postFile(uploader, mVFileID, mAssetType, this);
@@ -293,6 +297,7 @@ void LLAssetUploadResponder::uploadUpload(const LLSD& content)
 
 void LLAssetUploadResponder::uploadFailure(const LLSD& content)
 {
+	llwarns << dumpResponse() << llendl;
 	// remove the "Uploading..." message
 	LLUploadDialog::modalUploadFinished();
 	LLFloater* floater_snapshot = LLFloaterReg::findInstance("snapshot");
@@ -301,7 +306,7 @@ void LLAssetUploadResponder::uploadFailure(const LLSD& content)
 		floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "inventory")));
 	}
 	
-	std::string reason = content["state"];
+	const std::string& reason = content["state"].asStringRef();
 	// deal with L$ errors
 	if (reason == "insufficient funds")
 	{
@@ -340,9 +345,9 @@ LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(
 }
 
 // virtual
-void LLNewAgentInventoryResponder::errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
+void LLNewAgentInventoryResponder::httpFailure()
 {
-	LLAssetUploadResponder::errorWithContent(statusNum, reason, content);
+	LLAssetUploadResponder::httpFailure();
 	//LLImportColladaAssetCache::getInstance()->assetUploaded(mVFileID, LLUUID(), FALSE);
 }
 
@@ -487,10 +492,9 @@ void LLSendTexLayerResponder::uploadComplete(const LLSD& content)
 	}
 }
 
-void LLSendTexLayerResponder::errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
+void LLSendTexLayerResponder::httpFailure()
 {
-	llinfos << "LLSendTexLayerResponder error [status:"
-			<< statusNum << "]: " << content << llendl;
+	llwarns << dumpResponse() << llendl;
 	
 	// Invoke the original callback with an error result
 	LLViewerTexLayerSetBuffer::onTextureUploadComplete(LLUUID(), (void*) mBakedUploadData, -1, LL_EXSTAT_NONE);
@@ -1009,19 +1013,14 @@ LLNewAgentInventoryVariablePriceResponder::~LLNewAgentInventoryVariablePriceResp
 	delete mImpl;
 }
 
-void LLNewAgentInventoryVariablePriceResponder::errorWithContent(
-	U32 statusNum,
-	const std::string& reason,
-	const LLSD& content)
+void LLNewAgentInventoryVariablePriceResponder::httpFailure()
 {
-	lldebugs 
-		<< "LLNewAgentInventoryVariablePrice::error " << statusNum 
-		<< " reason: " << reason << llendl;
+	const LLSD& content = getContent();
+	LL_WARNS("Upload") << dumpResponse() << LL_ENDL;
 
-	if ( content.has("error") )
+	static const std::string _ERROR = "error";
+	if ( content.has(_ERROR) )
 	{
-		static const std::string _ERROR = "error";
-
 		mImpl->onTransportError(content[_ERROR]);
 	}
 	else
@@ -1030,8 +1029,14 @@ void LLNewAgentInventoryVariablePriceResponder::errorWithContent(
 	}
 }
 
-void LLNewAgentInventoryVariablePriceResponder::result(const LLSD& content)
+void LLNewAgentInventoryVariablePriceResponder::httpSuccess()
 {
+	const LLSD& content = getContent();
+	if (!content.isMap())
+	{
+		failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+		return;
+	}
 	// Parse out application level errors and the appropriate
 	// responses for them
 	static const std::string _ERROR = "error";
@@ -1047,6 +1052,7 @@ void LLNewAgentInventoryVariablePriceResponder::result(const LLSD& content)
 	// Check for application level errors
 	if ( content.has(_ERROR) )
 	{
+		LL_WARNS("Upload") << dumpResponse() << LL_ENDL;
 		onApplicationLevelError(content[_ERROR]);
 		return;
 	}
@@ -1090,6 +1096,7 @@ void LLNewAgentInventoryVariablePriceResponder::result(const LLSD& content)
 	}
 	else
 	{
+		LL_WARNS("Upload") << dumpResponse() << LL_ENDL;
 		onApplicationLevelError("");
 	}
 }
diff --git a/indra/newview/llassetuploadresponders.h b/indra/newview/llassetuploadresponders.h
index a6d1016136c6a49f86578e4077bf1acc010a822d..abfdc4ca7712e84a2555d48dd78032d7f3a9aab3 100644
--- a/indra/newview/llassetuploadresponders.h
+++ b/indra/newview/llassetuploadresponders.h
@@ -33,6 +33,8 @@
 // via capabilities
 class LLAssetUploadResponder : public LLHTTPClient::Responder
 {
+protected:
+	LOG_CLASS(LLAssetUploadResponder);
 public:
 	LLAssetUploadResponder(const LLSD& post_data,
 							const LLUUID& vfile_id,
@@ -42,8 +44,11 @@ class LLAssetUploadResponder : public LLHTTPClient::Responder
 							LLAssetType::EType asset_type);
 	~LLAssetUploadResponder();
 
-    virtual void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content);
-	virtual void result(const LLSD& content);
+protected:
+	virtual void httpFailure();
+	virtual void httpSuccess();
+
+public:
 	virtual void uploadUpload(const LLSD& content);
 	virtual void uploadComplete(const LLSD& content);
 	virtual void uploadFailure(const LLSD& content);
@@ -58,6 +63,7 @@ class LLAssetUploadResponder : public LLHTTPClient::Responder
 // TODO*: Remove this once deprecated
 class LLNewAgentInventoryResponder : public LLAssetUploadResponder
 {
+	LOG_CLASS(LLNewAgentInventoryResponder);
 public:
 	LLNewAgentInventoryResponder(
 		const LLSD& post_data,
@@ -67,9 +73,10 @@ class LLNewAgentInventoryResponder : public LLAssetUploadResponder
 		const LLSD& post_data,
 		const std::string& file_name,
 		LLAssetType::EType asset_type);
-    virtual void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content);
 	virtual void uploadComplete(const LLSD& content);
 	virtual void uploadFailure(const LLSD& content);
+protected:
+	virtual void httpFailure();
 };
 
 // A base class which goes through and performs some default
@@ -79,6 +86,7 @@ class LLNewAgentInventoryResponder : public LLAssetUploadResponder
 class LLNewAgentInventoryVariablePriceResponder :
 	public LLHTTPClient::Responder
 {
+	LOG_CLASS(LLNewAgentInventoryVariablePriceResponder);
 public:
 	LLNewAgentInventoryVariablePriceResponder(
 		const LLUUID& vfile_id,
@@ -91,12 +99,11 @@ class LLNewAgentInventoryVariablePriceResponder :
 		const LLSD& inventory_info);
 	virtual ~LLNewAgentInventoryVariablePriceResponder();
 
-	void errorWithContent(
-		U32 statusNum,
-		const std::string& reason,
-		const LLSD& content);
-	void result(const LLSD& content);
+private:
+	/* virtual */ void httpFailure();
+	/* virtual */ void httpSuccess();
 
+public:
 	virtual void onApplicationLevelError(
 		const LLSD& error);
 	virtual void showConfirmationDialog(
@@ -122,8 +129,11 @@ class LLSendTexLayerResponder : public LLAssetUploadResponder
 	~LLSendTexLayerResponder();
 
 	virtual void uploadComplete(const LLSD& content);
-	virtual void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content);
 
+protected:
+	virtual void httpFailure();
+
+private:
 	LLBakedUploadData * mBakedUploadData;
 };
 
diff --git a/indra/newview/llclassifiedstatsresponder.cpp b/indra/newview/llclassifiedstatsresponder.cpp
index e3cd83e174211bc4bcd997285adf96c93fedf899..923662e8872539f8da86368114b33fbb1e17c633 100644
--- a/indra/newview/llclassifiedstatsresponder.cpp
+++ b/indra/newview/llclassifiedstatsresponder.cpp
@@ -44,8 +44,14 @@ mClassifiedID(classified_id)
 }
 
 /*virtual*/
-void LLClassifiedStatsResponder::result(const LLSD& content)
+void LLClassifiedStatsResponder::httpSuccess()
 {
+	const LLSD& content = getContent();
+	if (!content.isMap())
+	{
+		failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+		return;
+	}
 	S32 teleport = content["teleport_clicks"].asInteger();
 	S32 map = content["map_clicks"].asInteger();
 	S32 profile = content["profile_clicks"].asInteger();
@@ -62,7 +68,8 @@ void LLClassifiedStatsResponder::result(const LLSD& content)
 }
 
 /*virtual*/
-void LLClassifiedStatsResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+void LLClassifiedStatsResponder::httpFailure()
 {
-	llinfos << "LLClassifiedStatsResponder::error [status:" << status << "]: " << content << llendl;
+	llwarns << dumpResponse() << llendl;
 }
+
diff --git a/indra/newview/llclassifiedstatsresponder.h b/indra/newview/llclassifiedstatsresponder.h
index 06dcb62fd055e6ad4fadf8ccdae343e01602c920..efa4d82411d2df7dd4d598476a02ef107ed206d9 100644
--- a/indra/newview/llclassifiedstatsresponder.h
+++ b/indra/newview/llclassifiedstatsresponder.h
@@ -33,13 +33,15 @@
 
 class LLClassifiedStatsResponder : public LLHTTPClient::Responder
 {
+	LOG_CLASS(LLClassifiedStatsResponder);
 public:
 	LLClassifiedStatsResponder(LLUUID classified_id);
+
+protected:
 	//If we get back a normal response, handle it here
-	virtual void result(const LLSD& content);
+	virtual void httpSuccess();
 	//If we get back an error (not found, etc...), handle it here
-	
-	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
+	virtual void httpFailure();
 
 protected:
 	LLUUID mClassifiedID;
diff --git a/indra/newview/llestateinfomodel.cpp b/indra/newview/llestateinfomodel.cpp
index 2669b0340fbef96ce1b72b8114fda1c77326d13a..db2c15a4444a0351ab198321cbceabbf5dc6b86a 100644
--- a/indra/newview/llestateinfomodel.cpp
+++ b/indra/newview/llestateinfomodel.cpp
@@ -112,19 +112,19 @@ void LLEstateInfoModel::notifyCommit()
 
 class LLEstateChangeInfoResponder : public LLHTTPClient::Responder
 {
-public:
-
+	LOG_CLASS(LLEstateChangeInfoResponder);
+protected:
 	// if we get a normal response, handle it here
-	virtual void result(const LLSD& content)
+	virtual void httpSuccesss()
 	{
 		llinfos << "Committed estate info" << llendl;
 		LLEstateInfoModel::instance().notifyCommit();
 	}
 
 	// if we get an error response
-	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+	virtual void httpFailure()
 	{
-		llwarns << "Failed to commit estate info [status:" << status << "]: " << content << llendl;
+		llwarns << "Failed to commit estate info " << dumpResponse() << llendl;
 	}
 };
 
diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp
index e0f7223a8ce745949d1ee8c60df93da53f322f74..c3b53d5e4aa617fbfd9f820a50190af0258fd9a0 100644
--- a/indra/newview/lleventpoll.cpp
+++ b/indra/newview/lleventpoll.cpp
@@ -31,7 +31,7 @@
 #include "llagent.h"
 
 #include "llhttpclient.h"
-#include "llhttpstatuscodes.h"
+#include "llhttpconstants.h"
 #include "llsdserialize.h"
 #include "lleventtimer.h"
 #include "llviewerregion.h"
@@ -49,6 +49,7 @@ namespace
 
 	class LLEventPollResponder : public LLHTTPClient::Responder
 	{
+		LOG_CLASS(LLEventPollResponder);
 	public:
 		
 		static LLHTTPClient::ResponderPtr start(const std::string& pollURL, const LLHost& sender);
@@ -56,19 +57,19 @@ namespace
 		
 		void makeRequest();
 
+		/* virtual */ void completedRaw(const LLChannelDescriptors& channels,
+								  const LLIOPipe::buffer_ptr_t& buffer);
+
 	private:
 		LLEventPollResponder(const std::string&	pollURL, const LLHost& sender);
 		~LLEventPollResponder();
 
 		
 		void handleMessage(const LLSD& content);
-		virtual	void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
-		virtual	void result(const LLSD&	content);
 
-		virtual void completedRaw(U32 status,
-									const std::string& reason,
-									const LLChannelDescriptors& channels,
-									const LLIOPipe::buffer_ptr_t& buffer);
+		/* virtual */ void httpFailure();
+		/* virtual */ void httpSuccess();
+
 	private:
 
 		bool	mDone;
@@ -149,20 +150,18 @@ namespace
 	}
 
 	// virtual 
-	void LLEventPollResponder::completedRaw(U32 status,
-									const std::string& reason,
-									const LLChannelDescriptors& channels,
-									const LLIOPipe::buffer_ptr_t& buffer)
+	void LLEventPollResponder::completedRaw(const LLChannelDescriptors& channels,
+											const LLIOPipe::buffer_ptr_t& buffer)
 	{
-		if (status == HTTP_BAD_GATEWAY)
+		if (getStatus() == HTTP_BAD_GATEWAY)
 		{
 			// These errors are not parsable as LLSD, 
 			// which LLHTTPClient::Responder::completedRaw will try to do.
-			completed(status, reason, LLSD());
+			httpCompleted();
 		}
 		else
 		{
-			LLHTTPClient::Responder::completedRaw(status,reason,channels,buffer);
+			LLHTTPClient::Responder::completedRaw(channels,buffer);
 		}
 	}
 
@@ -187,13 +186,13 @@ namespace
 	}
 
 	//virtual
-	void LLEventPollResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+	void LLEventPollResponder::httpFailure()
 	{
 		if (mDone) return;
 
 		// A HTTP_BAD_GATEWAY (502) error is our standard timeout response
 		// we get this when there are no events.
-		if ( status == HTTP_BAD_GATEWAY )	
+		if ( getStatus() == HTTP_BAD_GATEWAY )
 		{
 			mErrorCount = 0;
 			makeRequest();
@@ -207,12 +206,12 @@ namespace
 										+ mErrorCount * EVENT_POLL_ERROR_RETRY_SECONDS_INC
 									, this);
 
-			llwarns << "LLEventPollResponder error [status:" << status << "]: " << content << llendl;
+			llwarns << dumpResponse() << llendl;
 		}
 		else
 		{
-			llwarns << "LLEventPollResponder error <" << mCount 
-					<< "> [status:" << status << "]: " << content
+			llwarns << dumpResponse()
+					<< " [count:" << mCount << "] "
 					<< (mDone ? " -- done" : "") << llendl;
 			stop();
 
@@ -234,7 +233,7 @@ namespace
 	}
 
 	//virtual
-	void LLEventPollResponder::result(const LLSD& content)
+	void LLEventPollResponder::httpSuccess()
 	{
 		lldebugs <<	"LLEventPollResponder::result <" << mCount	<< ">"
 				 <<	(mDone ? " -- done"	: "") << llendl;
@@ -243,10 +242,12 @@ namespace
 
 		mErrorCount = 0;
 
-		if (!content.get("events") ||
+		const LLSD& content = getContent();
+		if (!content.isMap() ||
+			!content.get("events") ||
 			!content.get("id"))
 		{
-			llwarns << "received event poll with no events or id key" << llendl;
+			llwarns << "received event poll with no events or id key: " << dumpResponse() << llendl;
 			makeRequest();
 			return;
 		}
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index a4cadcd5dcf1b18f11f9558813510ad00071c5ed..c4ae7180829df1b8afedaf44a59855f3bb5d2e4b 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -39,6 +39,7 @@
 #include "llsecondlifeurls.h"
 
 #include "llappviewer.h"
+#include "llbufferstream.h"
 #include "llhttpclient.h"
 #include "llnotificationsutil.h"
 #include "llviewercontrol.h"
@@ -509,6 +510,7 @@ void LLFeatureManager::parseGPUTable(std::string filename)
 // responder saves table into file
 class LLHTTPFeatureTableResponder : public LLHTTPClient::Responder
 {
+	LOG_CLASS(LLHTTPFeatureTableResponder);
 public:
 
 	LLHTTPFeatureTableResponder(std::string filename) :
@@ -517,11 +519,10 @@ class LLHTTPFeatureTableResponder : public LLHTTPClient::Responder
 	}
 
 	
-	virtual void completedRaw(U32 status, const std::string& reason,
-							  const LLChannelDescriptors& channels,
+	virtual void completedRaw(const LLChannelDescriptors& channels,
 							  const LLIOPipe::buffer_ptr_t& buffer)
 	{
-		if (isGoodStatus(status))
+		if (isGoodStatus())
 		{
 			// write to file
 
@@ -540,7 +541,18 @@ class LLHTTPFeatureTableResponder : public LLHTTPClient::Responder
 				out.close();
 			}
 		}
-		
+		else
+		{
+			char body[1025]; 
+			body[1024] = '\0';
+			LLBufferStream istr(channels, buffer.get());
+			istr.get(body,1024);
+			if (strlen(body) > 0)
+			{
+				mContent["body"] = body;
+			}
+			llwarns << dumpResponse() << llendl;
+		}
 	}
 	
 private:
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index d13f85baa2ec0b2fd309dee63d6b2dcd67ffe2f9..89d74666f7437401414c7d2f72d25506f6cc2f7c 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -1240,9 +1240,9 @@ static std::string add_imageload_filter_to_gtkchooser(GtkWindow *picker)
 {
 	GtkFileFilter *gfilter = gtk_file_filter_new();
 	gtk_file_filter_add_pattern(gfilter, "*.tga");
-	gtk_file_filter_add_mime_type(gfilter, "image/jpeg");
-	gtk_file_filter_add_mime_type(gfilter, "image/png");
-	gtk_file_filter_add_mime_type(gfilter, "image/bmp");
+	gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_JPEG.c_str());
+	gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_PNG.c_str());
+	gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_BMP.c_str());
 	std::string filtername = LLTrans::getString("image_files") + " (*.tga; *.bmp; *.jpg; *.png)";
 	add_common_filters_to_gtkchooser(gfilter, picker, filtername);
 	return filtername;
@@ -1250,13 +1250,13 @@ static std::string add_imageload_filter_to_gtkchooser(GtkWindow *picker)
  
 static std::string add_script_filter_to_gtkchooser(GtkWindow *picker)
 {
-	return add_simple_mime_filter_to_gtkchooser(picker,  "text/plain",
+	return add_simple_mime_filter_to_gtkchooser(picker,  HTTP_CONTENT_TEXT_PLAIN,
 							LLTrans::getString("script_files") + " (*.lsl)");
 }
 
 static std::string add_dictionary_filter_to_gtkchooser(GtkWindow *picker)
 {
-	return add_simple_mime_filter_to_gtkchooser(picker,  "text/plain",
+	return add_simple_mime_filter_to_gtkchooser(picker, HTTP_CONTENT_TEXT_PLAIN,
 							LLTrans::getString("dictionary_files") + " (*.dic; *.xcu)");
 }
 
@@ -1294,7 +1294,7 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename
 			break;
 		case FFSAVE_BMP:
 			caption += add_simple_mime_filter_to_gtkchooser
-				(picker, "image/bmp", LLTrans::getString("bitmap_image_files") + " (*.bmp)");
+				(picker, HTTP_CONTENT_IMAGE_BMP, LLTrans::getString("bitmap_image_files") + " (*.bmp)");
 			suggest_ext = ".bmp";
 			break;
 		case FFSAVE_AVI:
@@ -1319,6 +1319,7 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename
 			suggest_ext = ".raw";
 			break;
 		case FFSAVE_J2C:
+			// *TODO: Should this be 'image/j2c' ?
 			caption += add_simple_mime_filter_to_gtkchooser
 				(picker, "images/jp2",
 				 LLTrans::getString("compressed_image_files") + " (*.j2c)");
diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index 83fb887d81b3e2ad2c19fa193886d19e7ba3aa3e..63888ace117cc528e3ae93bd0a72a8403d18d7b2 100644
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -77,14 +77,9 @@ class LLServerReleaseNotesURLFetcher : public LLHTTPClient::Responder
 {
 	LOG_CLASS(LLServerReleaseNotesURLFetcher);
 public:
-
 	static void startFetch();
-	/*virtual*/ void completedHeader(U32 status, const std::string& reason, const LLSD& content);
-	/*virtual*/ void completedRaw(
-		U32 status,
-		const std::string& reason,
-		const LLChannelDescriptors& channels,
-		const LLIOPipe::buffer_ptr_t& buffer);
+private:
+	/* virtual */ void httpCompleted();
 };
 
 ///----------------------------------------------------------------------------
@@ -471,32 +466,27 @@ void LLServerReleaseNotesURLFetcher::startFetch()
 }
 
 // virtual
-void LLServerReleaseNotesURLFetcher::completedHeader(U32 status, const std::string& reason, const LLSD& content)
+void LLServerReleaseNotesURLFetcher::httpCompleted()
 {
-	lldebugs << "Status: " << status << llendl;
-	lldebugs << "Reason: " << reason << llendl;
-	lldebugs << "Headers: " << content << llendl;
+	LL_DEBUGS("ServerReleaseNotes") << dumpResponse() 
+		<< " [headers:" << getResponseHeaders() << "]" << LL_ENDL;
 
 	LLFloaterAbout* floater_about = LLFloaterReg::getTypedInstance<LLFloaterAbout>("sl_about");
 	if (floater_about)
 	{
-		std::string location = content["location"].asString();
+		const bool check_lower = true;
+		const std::string& location = getResponseHeader(HTTP_HEADER_LOCATION, check_lower);
 		if (location.empty())
 		{
-			location = floater_about->getString("ErrorFetchingServerReleaseNotesURL");
+			LL_WARNS("ServerReleaseNotes") << "Missing Location header "
+				<< dumpResponse() << " [headers:" << getResponseHeaders() << "]" << LL_ENDL;
+			floater_about->updateServerReleaseNotesURL(
+						floater_about->getString("ErrorFetchingServerReleaseNotesURL"));
+		}
+		else
+		{
+			floater_about->updateServerReleaseNotesURL(location);
 		}
-		floater_about->updateServerReleaseNotesURL(location);
 	}
 }
 
-// virtual
-void LLServerReleaseNotesURLFetcher::completedRaw(
-	U32 status,
-	const std::string& reason,
-	const LLChannelDescriptors& channels,
-	const LLIOPipe::buffer_ptr_t& buffer)
-{
-	// Do nothing.
-	// We're overriding just because the base implementation tries to
-	// deserialize LLSD which triggers warnings.
-}
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index 752aba5e160d067696096b24a65df09bdb173a1d..eaf4d062feb5777d37d2cb2cba326d7cb93ff693 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -380,12 +380,14 @@ BOOL LLFloaterAvatarPicker::visibleItemsSelected() const
 
 class LLAvatarPickerResponder : public LLHTTPClient::Responder
 {
+	LOG_CLASS(LLAvatarPickerResponder);
 public:
 	LLUUID mQueryID;
 
 	LLAvatarPickerResponder(const LLUUID& id) : mQueryID(id) { }
 
-	/*virtual*/ void completed(U32 status, const std::string& reason, const LLSD& content)
+protected:
+	/*virtual*/ void httpCompleted()
 	{
 		//std::ostringstream ss;
 		//LLSDSerialize::toPrettyXML(content, ss);
@@ -393,19 +395,18 @@ class LLAvatarPickerResponder : public LLHTTPClient::Responder
 
 		// in case of invalid characters, the avatar picker returns a 400
 		// just set it to process so it displays 'not found'
-		if (isGoodStatus(status) || status == 400)
+		if (isGoodStatus() || getStatus() == HTTP_BAD_REQUEST)
 		{
 			LLFloaterAvatarPicker* floater =
 				LLFloaterReg::findTypedInstance<LLFloaterAvatarPicker>("avatar_picker");
 			if (floater)
 			{
-				floater->processResponse(mQueryID, content);
+				floater->processResponse(mQueryID, getContent());
 			}
 		}
 		else
 		{
-			llwarns << "avatar picker failed [status:" << status << "]: " << content << llendl;
-			
+			llwarns << "avatar picker failed " << dumpResponse() << llendl;
 		}
 	}
 };
diff --git a/indra/newview/llfloaterbuycurrencyhtml.cpp b/indra/newview/llfloaterbuycurrencyhtml.cpp
index 013cf74c7bab3ee8260090ba21d204943a0134df..6e641e7d40bca94ff2584fedae7bfed82198da6e 100644
--- a/indra/newview/llfloaterbuycurrencyhtml.cpp
+++ b/indra/newview/llfloaterbuycurrencyhtml.cpp
@@ -27,6 +27,7 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "llfloaterbuycurrencyhtml.h"
+#include "llhttpconstants.h"
 #include "llstatusbar.h"
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -85,7 +86,7 @@ void LLFloaterBuyCurrencyHTML::navigateToFinalURL()
 	llinfos << "Buy currency HTML parsed URL is " << buy_currency_url << llendl;
 
 	// kick off the navigation
-	mBrowser->navigateTo( buy_currency_url, "text/html" );
+	mBrowser->navigateTo( buy_currency_url, HTTP_CONTENT_TEXT_HTML );
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llfloaterhelpbrowser.cpp b/indra/newview/llfloaterhelpbrowser.cpp
index 4cb632bd6abf0c16b905d86aa9601e75c385b45a..c0bb2135405a1eae0414479714b48146b2637e3f 100644
--- a/indra/newview/llfloaterhelpbrowser.cpp
+++ b/indra/newview/llfloaterhelpbrowser.cpp
@@ -29,6 +29,7 @@
 #include "llfloaterhelpbrowser.h"
 
 #include "llfloaterreg.h"
+#include "llhttpconstants.h"
 #include "llpluginclassmedia.h"
 #include "llmediactrl.h"
 #include "llviewerwindow.h"
@@ -37,7 +38,6 @@
 #include "llui.h"
 
 #include "llurlhistory.h"
-#include "llmediactrl.h"
 #include "llviewermedia.h"
 #include "llviewerhelp.h"
 
@@ -148,7 +148,7 @@ void LLFloaterHelpBrowser::openMedia(const std::string& media_url)
 {
 	// explicitly make the media mime type for this floater since it will
 	// only ever display one type of content (Web).
-	mBrowser->setHomePageUrl(media_url, "text/html");
-	mBrowser->navigateTo(media_url, "text/html");
+	mBrowser->setHomePageUrl(media_url, HTTP_CONTENT_TEXT_HTML);
+	mBrowser->navigateTo(media_url, HTTP_CONTENT_TEXT_HTML);
 	setCurrentURL(media_url);
 }
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index c9f5b42b20533ff3b62af31c0cd2cdf0b3a140f9..c365666f00cede301e45651a7d49e6b5a3084a1c 100755
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -5839,7 +5839,7 @@ void LLFloaterModelPreview::handleModelPhysicsFeeReceived()
 	mUploadBtn->setEnabled(mHasUploadPerm && !mUploadModelUrl.empty());
 }
 
-void LLFloaterModelPreview::setModelPhysicsFeeErrorStatus(U32 status, const std::string& reason)
+void LLFloaterModelPreview::setModelPhysicsFeeErrorStatus(S32 status, const std::string& reason)
 {
 	llwarns << "LLFloaterModelPreview::setModelPhysicsFeeErrorStatus(" << status << " : " << reason << ")" << llendl;
 	doOnIdleOneTime(boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this, true));
@@ -5915,7 +5915,7 @@ void LLFloaterModelPreview::onPermissionsReceived(const LLSD& result)
 	getChild<LLTextBox>("warning_message")->setVisible(!mHasUploadPerm);
 }
 
-void LLFloaterModelPreview::setPermissonsErrorStatus(U32 status, const std::string& reason)
+void LLFloaterModelPreview::setPermissonsErrorStatus(S32 status, const std::string& reason)
 {
 	llwarns << "LLFloaterModelPreview::setPermissonsErrorStatus(" << status << " : " << reason << ")" << llendl;
 
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index e588418f7b1d7142fa07745040a176af93112f04..6c0c60b87fb648cf6322d4c806444971f0bb1aa1 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -200,11 +200,11 @@ class LLFloaterModelPreview : public LLFloaterModelUploadBase
 	/*virtual*/ void onPermissionsReceived(const LLSD& result);
 
 	// called when error occurs during permissions request
-	/*virtual*/ void setPermissonsErrorStatus(U32 status, const std::string& reason);
+	/*virtual*/ void setPermissonsErrorStatus(S32 status, const std::string& reason);
 
 	/*virtual*/ void onModelPhysicsFeeReceived(const LLSD& result, std::string upload_url);
 				void handleModelPhysicsFeeReceived();
-	/*virtual*/ void setModelPhysicsFeeErrorStatus(U32 status, const std::string& reason);
+	/*virtual*/ void setModelPhysicsFeeErrorStatus(S32 status, const std::string& reason);
 
 	/*virtual*/ void onModelUploadSuccess();
 
diff --git a/indra/newview/llfloatermodeluploadbase.cpp b/indra/newview/llfloatermodeluploadbase.cpp
index 6d3800bfa46f26a59bf2a12e941ab3796a0f01c3..9f1fc06e14e5e479e033c26b965221c3148d8522 100644
--- a/indra/newview/llfloatermodeluploadbase.cpp
+++ b/indra/newview/llfloatermodeluploadbase.cpp
@@ -45,7 +45,7 @@ void LLFloaterModelUploadBase::requestAgentUploadPermissions()
 	if (!url.empty())
 	{
 		llinfos<< typeid(*this).name() <<"::requestAgentUploadPermissions() requesting for upload model permissions from: "<< url <<llendl;
-		LLHTTPClient::get(url, new LLUploadModelPremissionsResponder(getPermObserverHandle()));
+		LLHTTPClient::get(url, new LLUploadModelPermissionsResponder(getPermObserverHandle()));
 	}
 	else
 	{
diff --git a/indra/newview/llfloatermodeluploadbase.h b/indra/newview/llfloatermodeluploadbase.h
index a52bc286874122d5dc64fe7473e8772f7e10f22d..d9a887968783f06749466660c6aa463e9ad562fc 100644
--- a/indra/newview/llfloatermodeluploadbase.h
+++ b/indra/newview/llfloatermodeluploadbase.h
@@ -37,13 +37,13 @@ class LLFloaterModelUploadBase : public LLFloater, public LLUploadPermissionsObs
 
 	virtual ~LLFloaterModelUploadBase(){};
 
-	virtual void setPermissonsErrorStatus(U32 status, const std::string& reason) = 0;
+	virtual void setPermissonsErrorStatus(S32 status, const std::string& reason) = 0;
 
 	virtual void onPermissionsReceived(const LLSD& result) = 0;
 
 	virtual void onModelPhysicsFeeReceived(const LLSD& result, std::string upload_url) = 0;
 
-	virtual void setModelPhysicsFeeErrorStatus(U32 status, const std::string& reason) = 0;
+	virtual void setModelPhysicsFeeErrorStatus(S32 status, const std::string& reason) = 0;
 
 	virtual void onModelUploadSuccess() {};
 
diff --git a/indra/newview/llfloaterobjectweights.cpp b/indra/newview/llfloaterobjectweights.cpp
index 0862cd2897e0a7abe4ff1b8232c028b9ad4cacdb..c11a0568a66b16acefe745adcafb591d015324e9 100644
--- a/indra/newview/llfloaterobjectweights.cpp
+++ b/indra/newview/llfloaterobjectweights.cpp
@@ -123,7 +123,7 @@ void LLFloaterObjectWeights::onWeightsUpdate(const SelectionCost& selection_cost
 }
 
 //virtual
-void LLFloaterObjectWeights::setErrorStatus(U32 status, const std::string& reason)
+void LLFloaterObjectWeights::setErrorStatus(S32 status, const std::string& reason)
 {
 	const std::string text = getString("nothing_selected");
 
diff --git a/indra/newview/llfloaterobjectweights.h b/indra/newview/llfloaterobjectweights.h
index 9a244573bef2ad3fded6d564765020a38a9f3a5e..1a2c317bad862171a9303d73b77a501534a60149 100644
--- a/indra/newview/llfloaterobjectweights.h
+++ b/indra/newview/llfloaterobjectweights.h
@@ -63,7 +63,7 @@ class LLFloaterObjectWeights : public LLFloater, LLAccountingCostObserver
 	/*virtual*/ void onOpen(const LLSD& key);
 
 	/*virtual*/ void onWeightsUpdate(const SelectionCost& selection_cost);
-	/*virtual*/ void setErrorStatus(U32 status, const std::string& reason);
+	/*virtual*/ void setErrorStatus(S32 status, const std::string& reason);
 
 	void updateLandImpacts(const LLParcel* parcel);
 	void refresh();
diff --git a/indra/newview/llfloaterregiondebugconsole.cpp b/indra/newview/llfloaterregiondebugconsole.cpp
index 0cde878055d8ec049fc768ba81f1276cf1d897c6..efc04ac358f7aec27a84e89fd298e782f016ac76 100644
--- a/indra/newview/llfloaterregiondebugconsole.cpp
+++ b/indra/newview/llfloaterregiondebugconsole.cpp
@@ -73,24 +73,29 @@ namespace
 	// called if this request times out.
 	class AsyncConsoleResponder : public LLHTTPClient::Responder
 	{
-	public:
+		LOG_CLASS(AsyncConsoleResponder);
+	protected:
 		/* virtual */
-		void errorWithContent(U32 status, const std::string& reason)
+		void httpFailure()
 		{
+			LL_WARNS("Console") << dumpResponse() << LL_ENDL;
 			sConsoleReplySignal(UNABLE_TO_SEND_COMMAND);
 		}
 	};
 
 	class ConsoleResponder : public LLHTTPClient::Responder
 	{
+		LOG_CLASS(ConsoleResponder);
 	public:
 		ConsoleResponder(LLTextEditor *output) : mOutput(output)
 		{
 		}
 
+	protected:
 		/*virtual*/
-		void error(U32 status, const std::string& reason)
+		void httpFailure()
 		{
+			LL_WARNS("Console") << dumpResponse() << LL_ENDL;
 			if (mOutput)
 			{
 				mOutput->appendText(
@@ -100,8 +105,10 @@ namespace
 		}
 
 		/*virtual*/
-		void result(const LLSD& content)
+		void httpSuccess()
 		{
+			const LLSD& content = getContent();
+			LL_DEBUGS("Console") << content << LL_ENDL;
 			if (mOutput)
 			{
 				mOutput->appendText(
@@ -109,6 +116,7 @@ namespace
 			}
 		}
 
+	public:
 		LLTextEditor * mOutput;
 	};
 
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 4a9ea5acf00b1eebaebf3184978ce743b4a389b4..6c0e91dd2c6bd30b6ebfa67149dfbc706693f702 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -754,12 +754,12 @@ bool LLPanelRegionGeneralInfo::onMessageCommit(const LLSD& notification, const L
 
 class ConsoleRequestResponder : public LLHTTPClient::Responder
 {
-public:
+	LOG_CLASS(ConsoleRequestResponder);
+protected:
 	/*virtual*/
-	void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+	void httpFailure()
 	{
-		llwarns << "ConsoleRequestResponder error requesting mesh_rez_enabled [status:"
-				<< status << "]: " << content << llendl;
+		llwarns << "error requesting mesh_rez_enabled " << dumpResponse() << llendl;
 	}
 };
 
@@ -767,12 +767,12 @@ class ConsoleRequestResponder : public LLHTTPClient::Responder
 // called if this request times out.
 class ConsoleUpdateResponder : public LLHTTPClient::Responder
 {
-public:
+	LOG_CLASS(ConsoleUpdateResponder);
+protected:
 	/* virtual */
-	void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+	void httpFailure()
 	{
-		llwarns << "ConsoleRequestResponder error updating mesh enabled region setting [status:"
-				<< status << "]: " << content << llendl;
+		llwarns << "error updating mesh enabled region setting " << dumpResponse() << llendl;
 	}
 };
 
@@ -2191,14 +2191,16 @@ void LLPanelEstateInfo::getEstateOwner()
 
 class LLEstateChangeInfoResponder : public LLHTTPClient::Responder
 {
+	LOG_CLASS(LLEstateChangeInfoResponder);
 public:
 	LLEstateChangeInfoResponder(LLPanelEstateInfo* panel)
 	{
 		mpPanel = panel->getHandle();
 	}
 	
+protected:
 	// if we get a normal response, handle it here
-	virtual void result(const LLSD& content)
+	virtual void httpSuccess()
 	{
 		LL_INFOS("Windlight") << "Successfully committed estate info" << llendl;
 
@@ -2209,10 +2211,9 @@ class LLEstateChangeInfoResponder : public LLHTTPClient::Responder
 	}
 	
 	// if we get an error response
-	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+	virtual void httpFailure()
 	{
-		llinfos << "LLEstateChangeInfoResponder::error [status:"
-			<< status << "]: " << content << llendl;
+		LL_WARNS("Windlight") << dumpResponse() << LL_ENDL;
 	}
 private:
 	LLHandle<LLPanel> mpPanel;
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index 685b566fa89aea58617c841471feddf61cb19c78..f7fca90ebdc3cb0f66a225a6f9a813a1aa81bbf0 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -692,16 +692,18 @@ class LLUserReportScreenshotResponder : public LLAssetUploadResponder
 
 class LLUserReportResponder : public LLHTTPClient::Responder
 {
+	LOG_CLASS(LLUserReportResponder);
 public:
 	LLUserReportResponder(): LLHTTPClient::Responder()  {}
 
-	void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
-	{
-		// *TODO do some user messaging here
-		LLUploadDialog::modalUploadFinished();
-	}
-	void result(const LLSD& content)
+private:
+	void httpCompleted()
 	{
+		if (!isGoodStatus())
+		{
+			// *TODO do some user messaging here
+			LL_WARNS("UserReport") << dumpResponse() << LL_ENDL;
+		}
 		// we don't care about what the server returns
 		LLUploadDialog::modalUploadFinished();
 	}
diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp
index 17c34f1da05586fcf342ca29e155384dddfff3e2..7e94784751724716278aca584015ef29e8a93b10 100644
--- a/indra/newview/llfloaterscriptlimits.cpp
+++ b/indra/newview/llfloaterscriptlimits.cpp
@@ -183,8 +183,14 @@ void LLPanelScriptLimitsInfo::updateChild(LLUICtrl* child_ctr)
 // Responders
 ///----------------------------------------------------------------------------
 
-void fetchScriptLimitsRegionInfoResponder::result(const LLSD& content)
+void fetchScriptLimitsRegionInfoResponder::httpSuccess()
 {
+	const LLSD& content = getContent();
+	if (!content.isMap())
+	{
+		failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+		return;
+	}
 	//we don't need to test with a fake respose here (shouldn't anyway)
 
 #ifdef DUMP_REPLIES_TO_LLINFOS
@@ -221,13 +227,14 @@ void fetchScriptLimitsRegionInfoResponder::result(const LLSD& content)
 	}
 }
 
-void fetchScriptLimitsRegionInfoResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+void fetchScriptLimitsRegionInfoResponder::httpFailure()
 {
-	llwarns << "fetchScriptLimitsRegionInfoResponder error [status:" << status << "]: " << content << llendl;
+	llwarns << dumpResponse() << llendl;
 }
 
-void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content_ref)
+void fetchScriptLimitsRegionSummaryResponder::httpSuccess()
 {
+	const LLSD& content_ref = getContent();
 #ifdef USE_FAKE_RESPONSES
 
 	LLSD fake_content;
@@ -268,6 +275,12 @@ void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content_ref)
 
 #endif
 
+	if (!content.isMap())
+	{
+		failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+		return;
+	}
+
 
 #ifdef DUMP_REPLIES_TO_LLINFOS
 
@@ -291,7 +304,7 @@ void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content_ref)
 		LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");
 		if(tab)
 		{
-		LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel");
+			LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel");
 			if(panel_memory)
 			{
 				panel_memory->getChild<LLUICtrl>("loading_text")->setValue(LLSD(std::string("")));
@@ -301,20 +314,21 @@ void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content_ref)
 				{
 					btn->setEnabled(true);
 				}
-				
-		panel_memory->setRegionSummary(content);
-	}
-}
+
+				panel_memory->setRegionSummary(content);
+			}
+		}
 	}
 }
 
-void fetchScriptLimitsRegionSummaryResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+void fetchScriptLimitsRegionSummaryResponder::httpFailure()
 {
-	llwarns << "fetchScriptLimitsRegionSummaryResponder error [status:" << status << "]: " << content << llendl;
+	llwarns << dumpResponse() << llendl;
 }
 
-void fetchScriptLimitsRegionDetailsResponder::result(const LLSD& content_ref)
+void fetchScriptLimitsRegionDetailsResponder::httpSuccess()
 {
+	const LLSD& content_ref = getContent();
 #ifdef USE_FAKE_RESPONSES
 /*
 Updated detail service, ** denotes field added:
@@ -377,6 +391,12 @@ result (map)
 
 #endif
 
+	if (!content.isMap())
+	{
+		failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+		return;
+	}
+
 #ifdef DUMP_REPLIES_TO_LLINFOS
 
 	LLSDNotationStreamer notation_streamer(content);
@@ -417,13 +437,14 @@ result (map)
 	}
 }
 
-void fetchScriptLimitsRegionDetailsResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+void fetchScriptLimitsRegionDetailsResponder::httpFailure()
 {
-	llwarns << "fetchScriptLimitsRegionDetailsResponder error [status:" << status << "]: " << content << llendl;
+	llwarns << dumpResponse() << llendl;
 }
 
-void fetchScriptLimitsAttachmentInfoResponder::result(const LLSD& content_ref)
+void fetchScriptLimitsAttachmentInfoResponder::httpSuccess()
 {
+	const LLSD& content_ref = getContent();
 
 #ifdef USE_FAKE_RESPONSES
 
@@ -465,6 +486,12 @@ void fetchScriptLimitsAttachmentInfoResponder::result(const LLSD& content_ref)
 
 #endif
 
+	if (!content.isMap())
+	{
+		failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+		return;
+	}
+
 #ifdef DUMP_REPLIES_TO_LLINFOS
 
 	LLSDNotationStreamer notation_streamer(content);
@@ -513,9 +540,9 @@ void fetchScriptLimitsAttachmentInfoResponder::result(const LLSD& content_ref)
 	}
 }
 
-void fetchScriptLimitsAttachmentInfoResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+void fetchScriptLimitsAttachmentInfoResponder::httpFailure()
 {
-	llwarns << "fetchScriptLimitsAttachmentInfoResponder error [status:" << status << "]: " << content << llendl;
+	llwarns << dumpResponse() << llendl;
 }
 
 ///----------------------------------------------------------------------------
@@ -586,7 +613,7 @@ void LLPanelScriptLimitsRegionMemory::setParcelID(const LLUUID& parcel_id)
 }
 
 // virtual
-void LLPanelScriptLimitsRegionMemory::setErrorStatus(U32 status, const std::string& reason)
+void LLPanelScriptLimitsRegionMemory::setErrorStatus(S32 status, const std::string& reason)
 {
 	llwarns << "Can't handle remote parcel request."<< " Http Status: "<< status << ". Reason : "<< reason<<llendl;
 }
diff --git a/indra/newview/llfloaterscriptlimits.h b/indra/newview/llfloaterscriptlimits.h
index f8732ef94bb02f14db6c46cf0b2661e24953eb50..a5cb1b6184a571b4ad00f73ccf7b3a757c11ae3a 100644
--- a/indra/newview/llfloaterscriptlimits.h
+++ b/indra/newview/llfloaterscriptlimits.h
@@ -85,49 +85,49 @@ class LLPanelScriptLimitsInfo : public LLPanel
 
 class fetchScriptLimitsRegionInfoResponder: public LLHTTPClient::Responder
 {
-	public:
-		fetchScriptLimitsRegionInfoResponder(const LLSD& info) : mInfo(info) {};
-
-		void result(const LLSD& content);
-		void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
-	public:
-	protected:
-		LLSD mInfo;
+	LOG_CLASS(fetchScriptLimitsRegionInfoResponder);
+public:
+	fetchScriptLimitsRegionInfoResponder(const LLSD& info) : mInfo(info) {};
+
+private:
+	/* virtual */ void httpSuccess();
+	/* virtual */ void httpFailure();
+	LLSD mInfo;
 };
 
 class fetchScriptLimitsRegionSummaryResponder: public LLHTTPClient::Responder
 {
-	public:
-		fetchScriptLimitsRegionSummaryResponder(const LLSD& info) : mInfo(info) {};
-
-		void result(const LLSD& content);
-		void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
-	public:
-	protected:
-		LLSD mInfo;
+	LOG_CLASS(fetchScriptLimitsRegionSummaryResponder);
+public:
+	fetchScriptLimitsRegionSummaryResponder(const LLSD& info) : mInfo(info) {};
+
+private:
+	/* virtual */ void httpSuccess();
+	/* virtual */ void httpFailure();
+	LLSD mInfo;
 };
 
 class fetchScriptLimitsRegionDetailsResponder: public LLHTTPClient::Responder
 {
-	public:
-		fetchScriptLimitsRegionDetailsResponder(const LLSD& info) : mInfo(info) {};
-
-		void result(const LLSD& content);
-		void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
-	public:
-	protected:
-		LLSD mInfo;
+	LOG_CLASS(fetchScriptLimitsRegionDetailsResponder);
+public:
+	fetchScriptLimitsRegionDetailsResponder(const LLSD& info) : mInfo(info) {};
+
+private:
+	/* virtual */ void httpSuccess();
+	/* virtual */ void httpFailure();
+	LLSD mInfo;
 };
 
 class fetchScriptLimitsAttachmentInfoResponder: public LLHTTPClient::Responder
 {
-	public:
-		fetchScriptLimitsAttachmentInfoResponder() {};
+	LOG_CLASS(fetchScriptLimitsAttachmentInfoResponder);
+public:
+	fetchScriptLimitsAttachmentInfoResponder() {};
 
-		void result(const LLSD& content);
-		void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
-	public:
-	protected:
+private:
+	/* virtual */ void httpSuccess();
+	/* virtual */ void httpFailure();
 };
 
 /////////////////////////////////////////////////////////////////////////////
@@ -190,7 +190,7 @@ class LLPanelScriptLimitsRegionMemory : public LLPanelScriptLimitsInfo, LLRemote
 // LLRemoteParcelInfoObserver interface:
 /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
 /*virtual*/ void setParcelID(const LLUUID& parcel_id);
-/*virtual*/ void setErrorStatus(U32 status, const std::string& reason);
+/*virtual*/ void setErrorStatus(S32 status, const std::string& reason);
 	
 	static void onClickRefresh(void* userdata);
 	static void onClickHighlight(void* userdata);
diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp
index 2a946b1edfa06048dc610ae01cc7c940361149f5..a446b767acb0bef9daba63dd35e50f0004f41f7a 100644
--- a/indra/newview/llfloatersearch.cpp
+++ b/indra/newview/llfloatersearch.cpp
@@ -30,6 +30,7 @@
 #include "llcommandhandler.h"
 #include "llfloaterreg.h"
 #include "llfloatersearch.h"
+#include "llhttpconstants.h"
 #include "llmediactrl.h"
 #include "llnotificationsutil.h"
 #include "lllogininstance.h"
@@ -200,5 +201,5 @@ void LLFloaterSearch::search(const SearchQuery &p)
 	url = LLWeb::expandURLSubstitutions(url, subs);
 
 	// and load the URL in the web view
-	mWebBrowser->navigateTo(url, "text/html");
+	mWebBrowser->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
 }
diff --git a/indra/newview/llfloatertos.cpp b/indra/newview/llfloatertos.cpp
index a242b224cd7fab1b538d4edad4bd287a8c1afc5b..0613ffc94d803f35e31e9d5a017c75d126cbe855 100644
--- a/indra/newview/llfloatertos.cpp
+++ b/indra/newview/llfloatertos.cpp
@@ -36,7 +36,7 @@
 #include "llbutton.h"
 #include "llevents.h"
 #include "llhttpclient.h"
-#include "llhttpstatuscodes.h"	// for HTTP_FOUND
+#include "llhttpconstants.h"
 #include "llnotificationsutil.h"
 #include "llradiogroup.h"
 #include "lltextbox.h"
@@ -62,42 +62,46 @@ LLFloaterTOS::LLFloaterTOS(const LLSD& data)
 // on parent class indicating if the web server is working or not
 class LLIamHere : public LLHTTPClient::Responder
 {
-	private:
-		LLIamHere( LLFloaterTOS* parent ) :
-		   mParent( parent )
-		{}
+	LOG_CLASS(LLIamHere);
+private:
+	LLIamHere( LLFloaterTOS* parent ) :
+	   mParent( parent )
+	{}
 
-		LLFloaterTOS* mParent;
+	LLFloaterTOS* mParent;
 
-	public:
-
-		static LLIamHere* build( LLFloaterTOS* parent )
-		{
-			return new LLIamHere( parent );
-		};
-		
-		virtual void  setParent( LLFloaterTOS* parentIn )
-		{
-			mParent = parentIn;
-		};
-		
-		virtual void result( const LLSD& content )
+public:
+	static LLIamHere* build( LLFloaterTOS* parent )
+	{
+		return new LLIamHere( parent );
+	}
+	
+	virtual void  setParent( LLFloaterTOS* parentIn )
+	{
+		mParent = parentIn;
+	}
+	
+protected:
+	virtual void httpSuccess()
+	{
+		if ( mParent )
 		{
-			if ( mParent )
-				mParent->setSiteIsAlive( true );
-		};
+			mParent->setSiteIsAlive( true );
+		}
+	}
 
-		virtual void error( U32 status, const std::string& reason )
+	virtual void httpFailure()
+	{
+		LL_DEBUGS("LLIamHere") << dumpResponse() << LL_ENDL;
+		if ( mParent )
 		{
-			if ( mParent )
-			{
-				// *HACK: For purposes of this alive check, 302 Found
-				// (aka Moved Temporarily) is considered alive.  The web site
-				// redirects this link to a "cache busting" temporary URL. JC
-				bool alive = (status == HTTP_FOUND);
-				mParent->setSiteIsAlive( alive );
-			}
-		};
+			// *HACK: For purposes of this alive check, 302 Found
+			// (aka Moved Temporarily) is considered alive.  The web site
+			// redirects this link to a "cache busting" temporary URL. JC
+			bool alive = (getStatus() == HTTP_FOUND);
+			mParent->setSiteIsAlive( alive );
+		}
+	}
 };
 
 // this is global and not a class member to keep crud out of the header file
diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp
index e85d849c9ad3b0ddca38532d739eafe3a467e29f..0751c830d5f83fbc2e0f95ed31d83a2d2682cdc7 100644
--- a/indra/newview/llfloaterurlentry.cpp
+++ b/indra/newview/llfloaterurlentry.cpp
@@ -48,31 +48,31 @@ static LLFloaterURLEntry* sInstance = NULL;
 // on the Panel Land Media and to discover the MIME type
 class LLMediaTypeResponder : public LLHTTPClient::Responder
 {
+	LOG_CLASS(LLMediaTypeResponder);
 public:
 	LLMediaTypeResponder( const LLHandle<LLFloater> parent ) :
-	  mParent( parent )
-	  {}
-
-	  LLHandle<LLFloater> mParent;
-
-
-	  virtual void completedHeader(U32 status, const std::string& reason, const LLSD& content)
-	  {
-		  std::string media_type = content["content-type"].asString();
-		  std::string::size_type idx1 = media_type.find_first_of(";");
-		  std::string mime_type = media_type.substr(0, idx1);
-		  completeAny(status, mime_type);
-	  }
-
-	  void completeAny(U32 status, const std::string& mime_type)
-	  {
-		  // Set empty type to none/none.  Empty string is reserved for legacy parcels
-		  // which have no mime type set.
-		  std::string resolved_mime_type = ! mime_type.empty() ? mime_type : LLMIMETypes::getDefaultMimeType();
-		  LLFloaterURLEntry* floater_url_entry = (LLFloaterURLEntry*)mParent.get();
-		  if ( floater_url_entry )
-			  floater_url_entry->headerFetchComplete( status, resolved_mime_type );
-	  }
+		mParent( parent )
+	{}
+
+	LLHandle<LLFloater> mParent;
+
+private:
+	/* virtual */ void httpCompleted()
+	{
+		const bool check_lower = true;
+		const std::string& media_type = getResponseHeader(HTTP_HEADER_CONTENT_TYPE, check_lower);
+		std::string::size_type idx1 = media_type.find_first_of(";");
+		std::string mime_type = media_type.substr(0, idx1);
+
+		// Set empty type to none/none.  Empty string is reserved for legacy parcels
+		// which have no mime type set.
+		std::string resolved_mime_type = ! mime_type.empty() ? mime_type : LLMIMETypes::getDefaultMimeType();
+		LLFloaterURLEntry* floater_url_entry = (LLFloaterURLEntry*)mParent.get();
+		if ( floater_url_entry )
+		{
+			floater_url_entry->headerFetchComplete( getStatus(), resolved_mime_type );
+		}
+	}
 };
 
 //-----------------------------------------------------------------------------
@@ -136,7 +136,7 @@ void LLFloaterURLEntry::buildURLHistory()
 	}
 }
 
-void LLFloaterURLEntry::headerFetchComplete(U32 status, const std::string& mime_type)
+void LLFloaterURLEntry::headerFetchComplete(S32 status, const std::string& mime_type)
 {
 	LLPanelLandMedia* panel_media = dynamic_cast<LLPanelLandMedia*>(mPanelLandMediaHandle.get());
 	if (panel_media)
diff --git a/indra/newview/llfloaterurlentry.h b/indra/newview/llfloaterurlentry.h
index dfb49fe5ac97bdb8cd53d300a303aa6814971b14..bdd1ebe5921f5dbd01a48d694ab6c5a9e7c5ec57 100644
--- a/indra/newview/llfloaterurlentry.h
+++ b/indra/newview/llfloaterurlentry.h
@@ -40,7 +40,7 @@ class LLFloaterURLEntry : public LLFloater
 	// that panel via the handle.
 	static LLHandle<LLFloater> show(LLHandle<LLPanel> panel_land_media_handle, const std::string media_url);
 	/*virtual*/	BOOL	postBuild();
-	void headerFetchComplete(U32 status, const std::string& mime_type);
+	void headerFetchComplete(S32 status, const std::string& mime_type);
 
 	bool addURLToCombobox(const std::string& media_url);
 
diff --git a/indra/newview/llfloaterwebcontent.cpp b/indra/newview/llfloaterwebcontent.cpp
index 3fe2518de67230cb185fda3cc036366796cfd5aa..21b171446fd99470c3ab3d07e7bb51cc95387610 100644
--- a/indra/newview/llfloaterwebcontent.cpp
+++ b/indra/newview/llfloaterwebcontent.cpp
@@ -29,6 +29,7 @@
 #include "llcombobox.h"
 #include "lliconctrl.h"
 #include "llfloaterreg.h"
+#include "llhttpconstants.h"
 #include "lllayoutstack.h"
 #include "llpluginclassmedia.h"
 #include "llprogressbar.h"
@@ -234,9 +235,9 @@ void LLFloaterWebContent::open_media(const Params& p)
 {
 	// Specifying a mime type of text/html here causes the plugin system to skip the MIME type probe and just open a browser plugin.
 	LLViewerMedia::proxyWindowOpened(p.target(), p.id());
-	mWebBrowser->setHomePageUrl(p.url, "text/html");
+	mWebBrowser->setHomePageUrl(p.url, HTTP_CONTENT_TEXT_HTML);
 	mWebBrowser->setTarget(p.target);
-	mWebBrowser->navigateTo(p.url, "text/html");
+	mWebBrowser->navigateTo(p.url, HTTP_CONTENT_TEXT_HTML);
 	
 	set_current_url(p.url);
 
@@ -451,7 +452,7 @@ void LLFloaterWebContent::onEnterAddress()
 	std::string url = mAddressCombo->getValue().asString();
 	if ( url.length() > 0 )
 	{
-		mWebBrowser->navigateTo( url, "text/html");
+		mWebBrowser->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
 	};
 }
 
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index cbd844cdac07743deb4a444a3a602a5b5b44cdf3..472e3862ea0a317b0881548898e94c283f889b8a 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -1843,23 +1843,31 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id,
 // Responder class for capability group management
 class GroupMemberDataResponder : public LLHTTPClient::Responder
 {
+	LOG_CLASS(GroupMemberDataResponder);
 public:
-		GroupMemberDataResponder() {}
-		virtual ~GroupMemberDataResponder() {}
-		virtual void result(const LLSD& pContent);
-		virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);
+	GroupMemberDataResponder() {}
+	virtual ~GroupMemberDataResponder() {}
+
 private:
-		LLSD mMemberData;
+	/* virtual */ void httpSuccess();
+	/* virtual */ void httpFailure();
+	LLSD mMemberData;
 };
 
-void GroupMemberDataResponder::errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent)
+void GroupMemberDataResponder::httpFailure()
 {
-	LL_WARNS("GrpMgr") << "Error receiving group member data [status:" 
-		<< pStatus << "]: " << pContent << LL_ENDL;
+	LL_WARNS("GrpMgr") << "Error receiving group member data "
+		<< dumpResponse() << LL_ENDL;
 }
 
-void GroupMemberDataResponder::result(const LLSD& content)
+void GroupMemberDataResponder::httpSuccess()
 {
+	const LLSD& content = getContent();
+	if (!content.isMap())
+	{
+		failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+		return;
+	}
 	LLGroupMgr::processCapGroupMembersRequest(content);
 }
 
diff --git a/indra/newview/llhomelocationresponder.cpp b/indra/newview/llhomelocationresponder.cpp
index 37428c4a44b5769885613c4ffc247f0c3b63b5a4..b1286cccf2b7522c2d6dbc6fe0523966e416c858 100644
--- a/indra/newview/llhomelocationresponder.cpp
+++ b/indra/newview/llhomelocationresponder.cpp
@@ -33,71 +33,76 @@
 #include "llagent.h"
 #include "llviewerregion.h"
 
-void LLHomeLocationResponder::result( const LLSD& content )
+void LLHomeLocationResponder::httpSuccess()
 {
+  const LLSD& content = getContent();
   LLVector3 agent_pos;
   bool      error = true;
-		
+
   do {
-	
+
     // was the call to /agent/<agent-id>/home-location successful?
     // If not, we keep error set to true
     if( ! content.has("success") )
     {
       break;
     }
-		
+
     if( 0 != strncmp("true", content["success"].asString().c_str(), 4 ) )
     {
       break;
     }
-		
+
     // did the simulator return a "justified" home location?
     // If no, we keep error set to true
     if( ! content.has( "HomeLocation" ) )
     {
       break;
     }
-		
+
     if( ! content["HomeLocation"].has("LocationPos") )
     {
       break;
     }
-		
+
     if( ! content["HomeLocation"]["LocationPos"].has("X") )
     {
       break;
     }
 
     agent_pos.mV[VX] = content["HomeLocation"]["LocationPos"]["X"].asInteger();
-		
+
     if( ! content["HomeLocation"]["LocationPos"].has("Y") )
     {
       break;
     }
 
     agent_pos.mV[VY] = content["HomeLocation"]["LocationPos"]["Y"].asInteger();
-		
+
     if( ! content["HomeLocation"]["LocationPos"].has("Z") )
     {
       break;
     }
 
     agent_pos.mV[VZ] = content["HomeLocation"]["LocationPos"]["Z"].asInteger();
-		
+
     error = false;
   } while( 0 );
-	
-  if( ! error )
+
+  if( error )
+  {
+    failureResult(HTTP_INTERNAL_ERROR, "Invalid server response content", content);
+  }
+  else
   {
     llinfos << "setting home position" << llendl;
-		
+
     LLViewerRegion *viewer_region = gAgent.getRegion();
     gAgent.setHomePosRegion( viewer_region->getHandle(), agent_pos );
   }
 }
 
-void LLHomeLocationResponder::errorWithContent( U32 status, const std::string& reason, const LLSD& content )
+void LLHomeLocationResponder::httpFailure()
 {
-	llwarns << "LLHomeLocationResponder error [status:" << status << "]: " << content << llendl;
+  llwarns << dumpResponse() << llendl;
 }
diff --git a/indra/newview/llhomelocationresponder.h b/indra/newview/llhomelocationresponder.h
index 9bf4b12c4e9eef85c5e5cbd45de4b9fa220f2f35..adc6c8cb58109b11e5333c63b9dafbc0ae2ccb55 100644
--- a/indra/newview/llhomelocationresponder.h
+++ b/indra/newview/llhomelocationresponder.h
@@ -35,8 +35,10 @@
 /* Typedef, Enum, Class, Struct, etc. */
 class LLHomeLocationResponder : public LLHTTPClient::Responder
 {
-	virtual void result( const LLSD& content );
-	virtual void errorWithContent( U32 status, const std::string& reason, const LLSD& content );
+	LOG_CLASS(LLHomeLocationResponder);
+private:
+	/* virtual */ void httpSuccess();
+	/* virtual */ void httpFailure();
 };
 
 #endif
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index fff178f8fee030d350ca0232606dc16cb312775d..c933d5428da4806429113509ce30cadfec15b252 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -979,16 +979,17 @@ BOOL LLIMFloater::isInviteAllowed() const
 
 class LLSessionInviteResponder : public LLHTTPClient::Responder
 {
+	LOG_CLASS(LLSessionInviteResponder);
 public:
 	LLSessionInviteResponder(const LLUUID& session_id)
 	{
 		mSessionID = session_id;
 	}
 
-	void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
+protected:
+	void httpFailure()
 	{
-		llwarns << "Error inviting all agents to session [status:" 
-				<< statusNum << "]: " << content << llendl;
+		llwarns << "Error inviting all agents to session " << dumpResponse() << llendl;
 		//throw something back to the viewer here?
 	}
 
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index 1dab0e67bf8913b541833a0fd7ac98f7e1ebad28..95ede326e60517874f40484ea50bd2dd6dd228db 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -388,16 +388,17 @@ void LLFloaterIMPanel::draw()
 
 class LLSessionInviteResponder : public LLHTTPClient::Responder
 {
+	LOG_CLASS(LLSessionInviteResponder);
 public:
 	LLSessionInviteResponder(const LLUUID& session_id)
 	{
 		mSessionID = session_id;
 	}
 
-	void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
+protected:
+	void httpFailure()
 	{
-		llwarns << "Error inviting all agents to session [status:" 
-				<< statusNum << "]: " << content << llendl;
+		llwarns << "Error inviting all agents to session " << dumpResponse() << llendl;
 		//throw something back to the viewer here?
 	}
 
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 20b33c5d08437e2196bd4f9ed8877ad3af516ac8..a00de8eb26b273a22674c8acbd1c61ed6ffdcb58 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -1214,6 +1214,7 @@ void start_deprecated_conference_chat(
 
 class LLStartConferenceChatResponder : public LLHTTPClient::Responder
 {
+	LOG_CLASS(LLStartConferenceChatResponder);
 public:
 	LLStartConferenceChatResponder(
 		const LLUUID& temp_session_id,
@@ -1227,10 +1228,12 @@ class LLStartConferenceChatResponder : public LLHTTPClient::Responder
 		mAgents = agents_to_invite;
 	}
 
-	virtual void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
+protected:
+	virtual void httpFailure()
 	{
 		//try an "old school" way.
-		if ( statusNum == 400 )
+		// *TODO: What about other error status codes?  4xx 5xx?
+		if ( getStatus() == HTTP_BAD_REQUEST )
 		{
 			start_deprecated_conference_chat(
 				mTempSessionID,
@@ -1239,8 +1242,7 @@ class LLStartConferenceChatResponder : public LLHTTPClient::Responder
 				mAgents);
 		}
 
-		llwarns << "LLStartConferenceChatResponder error [status:"
-				<< statusNum << "]: " << content << llendl;
+		llwarns << dumpResponse() << llendl;
 
 		//else throw an error back to the client?
 		//in theory we should have just have these error strings
@@ -1332,6 +1334,7 @@ bool LLIMModel::sendStartSession(
 class LLViewerChatterBoxInvitationAcceptResponder :
 	public LLHTTPClient::Responder
 {
+	LOG_CLASS(LLViewerChatterBoxInvitationAcceptResponder);
 public:
 	LLViewerChatterBoxInvitationAcceptResponder(
 		const LLUUID& session_id,
@@ -1341,8 +1344,15 @@ class LLViewerChatterBoxInvitationAcceptResponder :
 		mInvitiationType = invitation_type;
 	}
 
-	void result(const LLSD& content)
+private:
+	void httpSuccess()
 	{
+		const LLSD& content = getContent();
+		if (!content.isMap())
+		{
+			failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+			return;
+		}
 		if ( gIMMgr)
 		{
 			LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
@@ -1387,19 +1397,17 @@ class LLViewerChatterBoxInvitationAcceptResponder :
 		}
 	}
 
-	void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
+	void httpFailure()
 	{
-		llwarns << "LLViewerChatterBoxInvitationAcceptResponder error [status:"
-				<< statusNum << "]: " << content << llendl;
+		llwarns << dumpResponse() << llendl;
 		//throw something back to the viewer here?
 		if ( gIMMgr )
 		{
 			gIMMgr->clearPendingAgentListUpdates(mSessionID);
 			gIMMgr->clearPendingInvitation(mSessionID);
-			if ( 404 == statusNum )
+			if ( HTTP_NOT_FOUND == getStatus() )
 			{
-				std::string error_string;
-				error_string = "session_does_not_exist_error";
+				static const std::string error_string("session_does_not_exist_error");
 				gIMMgr->showSessionStartError(error_string, mSessionID);
 			}
 		}
diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp
index aafc43b02db0737f6207209b1a5a6465271602ed..1f719a22efb97ec135f76fcd8440018e29d1e683 100644
--- a/indra/newview/llinspectavatar.cpp
+++ b/indra/newview/llinspectavatar.cpp
@@ -495,21 +495,23 @@ void LLInspectAvatar::toggleSelectedVoice(bool enabled)
 
 		class MuteVoiceResponder : public LLHTTPClient::Responder
 		{
+			LOG_CLASS(MuteVoiceResponder);
 		public:
 			MuteVoiceResponder(const LLUUID& session_id)
 			{
 				mSessionID = session_id;
 			}
 
-			virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+		protected:
+			virtual void httpFailure()
 			{
-				llwarns << "MuteVoiceResponder error [status:" << status << "]: " << content << llendl;
+				llwarns << dumpResponse() << llendl;
 
 				if ( gIMMgr )
 				{
 					//403 == you're not a mod
 					//should be disabled if you're not a moderator
-					if ( 403 == status )
+					if ( HTTP_FORBIDDEN == getStatus() )
 					{
 						gIMMgr->showSessionEventError(
 							"mute",
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 99e72cdb22e5724431494ad87d12bfcf189264ed..0b2f80403d33e8d19a82bded024cb4c966ba5e39 100755
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -414,6 +414,7 @@ const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType prefe
 
 class LLCreateInventoryCategoryResponder : public LLHTTPClient::Responder
 {
+	LOG_CLASS(LLCreateInventoryCategoryResponder);
 public:
 	LLCreateInventoryCategoryResponder(LLInventoryModel* model, 
 									   void (*callback)(const LLSD&, void*),
@@ -424,16 +425,21 @@ class LLCreateInventoryCategoryResponder : public LLHTTPClient::Responder
 	{
 	}
 	
-	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+protected:
+	virtual void httpFailure()
 	{
-		LL_WARNS("InvAPI") << "CreateInventoryCategory failed [status:"
-				<< status << "]: " << content << LL_ENDL;
+		LL_WARNS("InvAPI") << dumpResponse() << LL_ENDL;
 	}
 	
-	virtual void result(const LLSD& content)
+	virtual void httpSuccess()
 	{
 		//Server has created folder.
-		
+		const LLSD& content = getContent();
+		if (!content.isMap() || !content.has("folder_id"))
+		{
+			failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+			return;
+		}
 		LLUUID category_id = content["folder_id"].asUUID();
 		
 		
@@ -1340,8 +1346,14 @@ void LLInventoryModel::addChangedMask(U32 mask, const LLUUID& referent)
 }
 
 // If we get back a normal response, handle it here
-void  LLInventoryModel::fetchInventoryResponder::result(const LLSD& content)
-{	
+void LLInventoryModel::fetchInventoryResponder::httpSuccess()
+{
+	const LLSD& content = getContent();
+	if (!content.isMap())
+	{
+		failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+		return;
+	}
 	start_new_inventory_observer();
 
 	/*LLUUID agent_id;
@@ -1400,9 +1412,9 @@ void  LLInventoryModel::fetchInventoryResponder::result(const LLSD& content)
 }
 
 //If we get back an error (not found, etc...), handle it here
-void LLInventoryModel::fetchInventoryResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+void LLInventoryModel::fetchInventoryResponder::httpFailure()
 {
-	llwarns << "fetchInventory error [status:" << status << "]: " << content << llendl;
+	llwarns << dumpResponse() << llendl;
 	gInventory.notifyObservers();
 }
 
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index dfdd237c9591a7ef81c7aa5262054c5799fa0f3b..9c2ca8cae9a1fb982ae855588b6611a96862af48 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -81,11 +81,12 @@ class LLInventoryModel
 
 	class fetchInventoryResponder : public LLHTTPClient::Responder
 	{
+		LOG_CLASS(fetchInventoryResponder);
 	public:
 		fetchInventoryResponder(const LLSD& request_sd) : mRequestSD(request_sd) {};
-		void result(const LLSD& content);			
-		void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 	protected:
+		virtual void httpSuccess();
+		virtual void httpFailure();
 		LLSD mRequestSD;
 	};
 
diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp
index f2b39e71863d35f0f962f47d78677b2031d90f75..e1537033f9339e4969d5efd53708611e19206758 100644
--- a/indra/newview/llinventorymodelbackgroundfetch.cpp
+++ b/indra/newview/llinventorymodelbackgroundfetch.cpp
@@ -363,35 +363,39 @@ void LLInventoryModelBackgroundFetch::incrFetchCount(S16 fetching)
 
 class LLInventoryModelFetchItemResponder : public LLInventoryModel::fetchInventoryResponder
 {
+	LOG_CLASS(LLInventoryModelFetchItemResponder);
 public:
 	LLInventoryModelFetchItemResponder(const LLSD& request_sd) : LLInventoryModel::fetchInventoryResponder(request_sd) {};
-	void result(const LLSD& content);			
-	void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
+private:
+	/* virtual */ void httpSuccess();
+	/* virtual */ void httpFailure();
 };
 
-void LLInventoryModelFetchItemResponder::result( const LLSD& content )
+void LLInventoryModelFetchItemResponder::httpSuccess()
 {
-	LLInventoryModel::fetchInventoryResponder::result(content);
+	LLInventoryModel::fetchInventoryResponder::httpSuccess();
 	LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1);
 }
 
-void LLInventoryModelFetchItemResponder::errorWithContent( U32 status, const std::string& reason, const LLSD& content )
+void LLInventoryModelFetchItemResponder::httpFailure()
 {
-	LLInventoryModel::fetchInventoryResponder::errorWithContent(status, reason, content);
+	LLInventoryModel::fetchInventoryResponder::httpFailure();
 	LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1);
 }
 
 
 class LLInventoryModelFetchDescendentsResponder: public LLHTTPClient::Responder
 {
+	LOG_CLASS(LLInventoryModelFetchDescendentsResponder);
 public:
 	LLInventoryModelFetchDescendentsResponder(const LLSD& request_sd, uuid_vec_t recursive_cats) : 
 		mRequestSD(request_sd),
 		mRecursiveCatUUIDs(recursive_cats)
 	{};
 	//LLInventoryModelFetchDescendentsResponder() {};
-	void result(const LLSD& content);
-	void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
+private:
+	/* virtual */ void httpSuccess();
+	/* virtual */ void httpFailure();
 protected:
 	BOOL getIsRecursive(const LLUUID& cat_id) const;
 private:
@@ -400,8 +404,14 @@ class LLInventoryModelFetchDescendentsResponder: public LLHTTPClient::Responder
 };
 
 // If we get back a normal response, handle it here.
-void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content)
+void LLInventoryModelFetchDescendentsResponder::httpSuccess()
 {
+	const LLSD& content = getContent();
+	if (!content.isMap())
+	{
+		failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+		return;
+	}
 	LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance();
 	if (content.has("folders"))	
 	{
@@ -508,11 +518,12 @@ void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content)
 		for(LLSD::array_const_iterator folder_it = content["bad_folders"].beginArray();
 			folder_it != content["bad_folders"].endArray();
 			++folder_it)
-		{	
+		{
+			// *TODO: Stop copying data
 			LLSD folder_sd = *folder_it;
 			
 			// These folders failed on the dataserver.  We probably don't want to retry them.
-			llinfos << "Folder " << folder_sd["folder_id"].asString() 
+			llwarns << "Folder " << folder_sd["folder_id"].asString() 
 					<< "Error: " << folder_sd["error"].asString() << llendl;
 		}
 	}
@@ -529,21 +540,19 @@ void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content)
 }
 
 // If we get back an error (not found, etc...), handle it here.
-void LLInventoryModelFetchDescendentsResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+void LLInventoryModelFetchDescendentsResponder::httpFailure()
 {
+	llwarns << dumpResponse() << llendl;
 	LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance();
 
-	llinfos << "LLInventoryModelFetchDescendentsResponder::error [status:"
-			<< status << "]: " << content << llendl;
-						
 	fetcher->incrFetchCount(-1);
 
-	if (status==499) // timed out
+	if (getStatus()==HTTP_INTERNAL_ERROR) // timed out or curl failure
 	{
 		for(LLSD::array_const_iterator folder_it = mRequestSD["folders"].beginArray();
 			folder_it != mRequestSD["folders"].endArray();
 			++folder_it)
-		{	
+		{
 			LLSD folder_sd = *folder_it;
 			LLUUID folder_id = folder_sd["folder_id"];
 			const BOOL recursive = getIsRecursive(folder_id);
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 0b009b68f74ae87e4854a767b8cf2ef9aecbd60f..bea1d62b933057bb45d5c7b7dd410bc6f5af1074 100644
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -99,7 +99,7 @@ namespace LLMarketplaceImport
 	bool hasSessionCookie();
 	bool inProgress();
 	bool resultPending();
-	U32 getResultStatus();
+	S32 getResultStatus();
 	const LLSD& getResults();
 
 	bool establishMarketplaceSessionCookie();
@@ -113,7 +113,7 @@ namespace LLMarketplaceImport
 	static bool sImportInProgress = false;
 	static bool sImportPostPending = false;
 	static bool sImportGetPending = false;
-	static U32 sImportResultStatus = 0;
+	static S32 sImportResultStatus = 0;
 	static LLSD sImportResults = LLSD::emptyMap();
 
 	static LLTimer slmGetTimer;
@@ -123,22 +123,22 @@ namespace LLMarketplaceImport
 	
 	class LLImportPostResponder : public LLHTTPClient::Responder
 	{
+		LOG_CLASS(LLImportPostResponder);
 	public:
 		LLImportPostResponder() : LLCurl::Responder() {}
-		
-		void completed(U32 status, const std::string& reason, const LLSD& content)
+
+	protected:
+		/* virtual */ void httpCompleted()
 		{
 			slmPostTimer.stop();
 
 			if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
 			{
-				llinfos << " SLM POST status: " << status << llendl;
-				llinfos << " SLM POST reason: " << reason << llendl;
-				llinfos << " SLM POST content: " << content.asString() << llendl;
-
-				llinfos << " SLM POST timer: " << slmPostTimer.getElapsedTimeF32() << llendl;
+				llinfos << " SLM [timer:" << slmPostTimer.getElapsedTimeF32() << "] "
+						<< dumpResponse() << llendl;
 			}
 
+			S32 status = getStatus();
 			if ((status == MarketplaceErrorCodes::IMPORT_REDIRECT) ||
 				(status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) ||
 				(status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT))
@@ -154,38 +154,36 @@ namespace LLMarketplaceImport
 			sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_DONE);
 			sImportPostPending = false;
 			sImportResultStatus = status;
-			sImportId = content;
+			sImportId = getContent();
 		}
 	};
 	
 	class LLImportGetResponder : public LLHTTPClient::Responder
 	{
+		LOG_CLASS(LLImportGetResponder);
 	public:
 		LLImportGetResponder() : LLCurl::Responder() {}
 		
-		void completedHeader(U32 status, const std::string& reason, const LLSD& content)
+	protected:
+		/* virtual */ void httpCompleted()
 		{
-			const std::string& set_cookie_string = content["set-cookie"].asString();
+			const bool check_lower = true;
+			const std::string& set_cookie_string = getResponseHeader(HTTP_HEADER_SET_COOKIE, check_lower);
 			
 			if (!set_cookie_string.empty())
 			{
 				sMarketplaceCookie = set_cookie_string;
 			}
-		}
-		
-		void completed(U32 status, const std::string& reason, const LLSD& content)
-		{
+
 			slmGetTimer.stop();
 
 			if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
 			{
-				llinfos << " SLM GET status: " << status << llendl;
-				llinfos << " SLM GET reason: " << reason << llendl;
-				llinfos << " SLM GET content: " << content.asString() << llendl;
-
-				llinfos << " SLM GET timer: " << slmGetTimer.getElapsedTimeF32() << llendl;
+				llinfos << " SLM [timer:" << slmGetTimer.getElapsedTimeF32() << "] "
+						<< dumpResponse() << llendl;
 			}
 			
+			S32 status = getStatus();
 			if ((status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) ||
 				(status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT))
 			{
@@ -200,7 +198,7 @@ namespace LLMarketplaceImport
 			sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_PROCESSING);
 			sImportGetPending = false;
 			sImportResultStatus = status;
-			sImportResults = content;
+			sImportResults = getContent();
 		}
 	};
 
@@ -221,7 +219,7 @@ namespace LLMarketplaceImport
 		return (sImportPostPending || sImportGetPending);
 	}
 	
-	U32 getResultStatus()
+	S32 getResultStatus()
 	{
 		return sImportResultStatus;
 	}
@@ -280,10 +278,10 @@ namespace LLMarketplaceImport
 
 		// Make the headers for the post
 		LLSD headers = LLSD::emptyMap();
-		headers["Accept"] = "*/*";
-		headers["Cookie"] = sMarketplaceCookie;
-		headers["Content-Type"] = "application/llsd+xml";
-		headers["User-Agent"] = LLViewerMedia::getCurrentUserAgent();
+		headers[HTTP_HEADER_ACCEPT] = "*/*";
+		headers[HTTP_HEADER_COOKIE] = sMarketplaceCookie;
+		headers[HTTP_HEADER_CONTENT_TYPE] = HTTP_CONTENT_LLSD_XML;
+		headers[HTTP_HEADER_USER_AGENT] = LLViewerMedia::getCurrentUserAgent();
 		
 		if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
 		{
@@ -313,11 +311,12 @@ namespace LLMarketplaceImport
 		
 		// Make the headers for the post
 		LLSD headers = LLSD::emptyMap();
-		headers["Accept"] = "*/*";
-		headers["Connection"] = "Keep-Alive";
-		headers["Cookie"] = sMarketplaceCookie;
-		headers["Content-Type"] = "application/xml";
-		headers["User-Agent"] = LLViewerMedia::getCurrentUserAgent();
+		headers[HTTP_HEADER_ACCEPT] = "*/*";
+		headers[HTTP_HEADER_CONNECTION] = "Keep-Alive";
+		headers[HTTP_HEADER_COOKIE] = sMarketplaceCookie;
+		// *TODO: Should this be 'application/llsd+xml'?
+		headers[HTTP_HEADER_CONTENT_TYPE] = HTTP_CONTENT_XML;
+		headers[HTTP_HEADER_USER_AGENT] = LLViewerMedia::getCurrentUserAgent();
 		
 		if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
 		{
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index 2075aeed63210d69a80e552a4f3361dc026b0eb3..cb5640b4da1656401ff3332ede0e6487dcf32e56 100644
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -52,6 +52,7 @@
 #include "llsdutil.h"
 #include "lllayoutstack.h"
 #include "lliconctrl.h"
+#include "llhttpconstants.h"
 #include "lltextbox.h"
 #include "llbutton.h"
 #include "llcheckboxctrl.h"
@@ -576,7 +577,7 @@ void LLMediaCtrl::navigateToLocalPage( const std::string& subdir, const std::str
 	{
 		mCurrentNavUrl = expanded_filename;
 		mMediaSource->setSize(mTextureWidth, mTextureHeight);
-		mMediaSource->navigateTo(expanded_filename, "text/html", false);
+		mMediaSource->navigateTo(expanded_filename, HTTP_CONTENT_TEXT_HTML, false);
 	}
 }
 
@@ -948,7 +949,7 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
 			LL_DEBUGS("Media") <<  "Media event:  MEDIA_EVENT_NAVIGATE_ERROR_PAGE" << LL_ENDL;
 			if ( mErrorPageURL.length() > 0 )
 			{
-				navigateTo(mErrorPageURL, "text/html");
+				navigateTo(mErrorPageURL, HTTP_CONTENT_TEXT_HTML);
 			};
 		};
 		break;
diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp
index e3b46d5d2f3fd7727d844cf69d51e1c3e94b330f..bc1aa087e572bb893465019e892c1e606ac7fc79 100644
--- a/indra/newview/llmediadataclient.cpp
+++ b/indra/newview/llmediadataclient.cpp
@@ -35,7 +35,7 @@
 
 #include <boost/lexical_cast.hpp>
 
-#include "llhttpstatuscodes.h"
+#include "llhttpconstants.h"
 #include "llsdutil.h"
 #include "llmediaentry.h"
 #include "lltextureentry.h"
@@ -564,7 +564,7 @@ LLMediaDataClient::Responder::Responder(const request_ptr_t &request)
 }
 
 /*virtual*/
-void LLMediaDataClient::Responder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+void LLMediaDataClient::Responder::httpFailure()
 {
 	mRequest->stopTracking();
 
@@ -574,9 +574,17 @@ void LLMediaDataClient::Responder::errorWithContent(U32 status, const std::strin
 		return;
 	}
 	
-	if (status == HTTP_SERVICE_UNAVAILABLE)
+	if (getStatus() == HTTP_SERVICE_UNAVAILABLE)
 	{
-		F32 retry_timeout = mRequest->getRetryTimerDelay();
+		F32 retry_timeout;
+#if 0
+		// *TODO: Honor server Retry-After header.
+		if (!hasResponseHeader(HTTP_HEADER_RETRY_AFTER)
+			|| !getSecondsUntilRetryAfter(getResponseHeader(HTTP_HEADER_RETRY_AFTER), retry_timeout))
+#endif
+		{
+			retry_timeout = mRequest->getRetryTimerDelay();
+		}
 		
 		mRequest->incRetryCount();
 		
@@ -594,15 +602,16 @@ void LLMediaDataClient::Responder::errorWithContent(U32 status, const std::strin
 				<< mRequest->getRetryCount() << " exceeds " << mRequest->getMaxNumRetries() << ", not retrying" << LL_ENDL;
 		}
 	}
+	// *TODO: Redirect on 3xx status codes.
 	else 
 	{
-		LL_WARNS("LLMediaDataClient") << *mRequest << " http error [status:" 
-				<< status << "]:" << content << ")" << LL_ENDL;
+		LL_WARNS("LLMediaDataClient") << *mRequest << " http failure "
+				<< dumpResponse() << LL_ENDL;
 	}
 }
 
 /*virtual*/
-void LLMediaDataClient::Responder::result(const LLSD& content)
+void LLMediaDataClient::Responder::httpSuccess()
 {
 	mRequest->stopTracking();
 
@@ -612,7 +621,7 @@ void LLMediaDataClient::Responder::result(const LLSD& content)
 		return;
 	}
 
-	LL_DEBUGS("LLMediaDataClientResponse") << *mRequest << " result : " << ll_print_sd(content) << LL_ENDL;
+	LL_DEBUGS("LLMediaDataClientResponse") << *mRequest << " " << dumpResponse() << LL_ENDL;
 }
 
 //////////////////////////////////////////////////////////////////////////////////////
@@ -876,7 +885,7 @@ LLMediaDataClient::Responder *LLObjectMediaDataClient::RequestUpdate::createResp
 
 
 /*virtual*/
-void LLObjectMediaDataClient::Responder::result(const LLSD& content)
+void LLObjectMediaDataClient::Responder::httpSuccess()
 {
 	getRequest()->stopTracking();
 
@@ -886,10 +895,16 @@ void LLObjectMediaDataClient::Responder::result(const LLSD& content)
 		return;
 	}
 
+	const LLSD& content = getContent();
+	if (!content.isMap())
+	{
+		failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+		return;
+	}
+
 	// This responder is only used for GET requests, not UPDATE.
+	LL_DEBUGS("LLMediaDataClientResponse") << *(getRequest()) << " " << dumpResponse() << LL_ENDL;
 
-	LL_DEBUGS("LLMediaDataClientResponse") << *(getRequest()) << " GET returned: " << ll_print_sd(content) << LL_ENDL;
-	
 	// Look for an error
 	if (content.has("error"))
 	{
@@ -1003,7 +1018,7 @@ LLMediaDataClient::Responder *LLObjectMediaNavigateClient::RequestNavigate::crea
 }
 
 /*virtual*/
-void LLObjectMediaNavigateClient::Responder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+void LLObjectMediaNavigateClient::Responder::httpFailure()
 {
 	getRequest()->stopTracking();
 
@@ -1015,14 +1030,14 @@ void LLObjectMediaNavigateClient::Responder::errorWithContent(U32 status, const
 
 	// Bounce back (unless HTTP_SERVICE_UNAVAILABLE, in which case call base
 	// class
-	if (status == HTTP_SERVICE_UNAVAILABLE)
+	if (getStatus() == HTTP_SERVICE_UNAVAILABLE)
 	{
-		LLMediaDataClient::Responder::errorWithContent(status, reason, content);
+		LLMediaDataClient::Responder::httpFailure();
 	}
 	else
 	{
 		// bounce the face back
-		LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error navigating: http code=" << status << LL_ENDL;
+		LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error navigating: " << dumpResponse() << LL_ENDL;
 		const LLSD &payload = getRequest()->getPayload();
 		// bounce the face back
 		getRequest()->getObject()->mediaNavigateBounceBack((LLSD::Integer)payload[LLTextureEntry::TEXTURE_INDEX_KEY]);
@@ -1030,7 +1045,7 @@ void LLObjectMediaNavigateClient::Responder::errorWithContent(U32 status, const
 }
 
 /*virtual*/
-void LLObjectMediaNavigateClient::Responder::result(const LLSD& content)
+void LLObjectMediaNavigateClient::Responder::httpSuccess()
 {
 	getRequest()->stopTracking();
 
@@ -1040,8 +1055,9 @@ void LLObjectMediaNavigateClient::Responder::result(const LLSD& content)
 		return;
 	}
 
-	LL_INFOS("LLMediaDataClient") << *(getRequest()) << " NAVIGATE returned " << ll_print_sd(content) << LL_ENDL;
+	LL_INFOS("LLMediaDataClient") << *(getRequest()) << " NAVIGATE returned " << dumpResponse() << LL_ENDL;
 	
+	const LLSD& content = getContent();
 	if (content.has("error"))
 	{
 		const LLSD &error = content["error"];
@@ -1065,6 +1081,6 @@ void LLObjectMediaNavigateClient::Responder::result(const LLSD& content)
 	else 
 	{
 		// No action required.
-		LL_DEBUGS("LLMediaDataClientResponse") << *(getRequest()) << " result : " << ll_print_sd(content) << LL_ENDL;
+		LL_DEBUGS("LLMediaDataClientResponse") << *(getRequest()) << " " << dumpResponse() << LL_ENDL;
 	}
 }
diff --git a/indra/newview/llmediadataclient.h b/indra/newview/llmediadataclient.h
index 89e20a28d097e95c732b206fb509a9ec7498ea61..231b883c32c6f9d157839a2911622a2604eda2a2 100644
--- a/indra/newview/llmediadataclient.h
+++ b/indra/newview/llmediadataclient.h
@@ -74,8 +74,9 @@ class LLMediaDataClientObject : public LLRefCount
 // Abstracts the Cap URL, the request, and the responder
 class LLMediaDataClient : public LLRefCount
 {
-public:
+protected:
     LOG_CLASS(LLMediaDataClient);
+public:
     
     const static F32 QUEUE_TIMER_DELAY;// = 1.0; // seconds(s)
 	const static F32 UNAVAILABLE_RETRY_TIMER_DELAY;// = 5.0; // secs
@@ -192,14 +193,16 @@ class LLMediaDataClient : public LLRefCount
 	// Responder
 	class Responder : public LLHTTPClient::Responder
 	{
+		LOG_CLASS(Responder);
 	public:
 		Responder(const request_ptr_t &request);
+		request_ptr_t &getRequest() { return mRequest; }
+
+	protected:
 		//If we get back an error (not found, etc...), handle it here
-		virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
+		virtual void httpFailure();
 		//If we get back a normal response, handle it here.	 Default just logs it.
-		virtual void result(const LLSD& content);
-
-		request_ptr_t &getRequest() { return mRequest; }
+		virtual void httpSuccess();
 
 	private:
 		request_ptr_t mRequest;
@@ -287,8 +290,9 @@ class LLMediaDataClient : public LLRefCount
 // MediaDataClient specific for the ObjectMedia cap
 class LLObjectMediaDataClient : public LLMediaDataClient
 {
-public:
+protected:
     LOG_CLASS(LLObjectMediaDataClient);
+public:
     LLObjectMediaDataClient(F32 queue_timer_delay = QUEUE_TIMER_DELAY,
 							F32 retry_timer_delay = UNAVAILABLE_RETRY_TIMER_DELAY,
 							U32 max_retries = MAX_RETRIES,
@@ -341,10 +345,12 @@ class LLObjectMediaDataClient : public LLMediaDataClient
 		    
     class Responder : public LLMediaDataClient::Responder
     {
+        LOG_CLASS(Responder);
     public:
         Responder(const request_ptr_t &request)
             : LLMediaDataClient::Responder(request) {}
-        virtual void result(const LLSD &content);
+    protected:
+        virtual void httpSuccess();
     };
 private:
 	// The Get/Update data client needs a second queue to avoid object updates starving load-ins.
@@ -362,8 +368,9 @@ class LLObjectMediaDataClient : public LLMediaDataClient
 // MediaDataClient specific for the ObjectMediaNavigate cap
 class LLObjectMediaNavigateClient : public LLMediaDataClient
 {
-public:
+protected:
     LOG_CLASS(LLObjectMediaNavigateClient);
+public:
 	// NOTE: from llmediaservice.h
 	static const int ERROR_PERMISSION_DENIED_CODE = 8002;
 	
@@ -397,11 +404,13 @@ class LLObjectMediaNavigateClient : public LLMediaDataClient
 
     class Responder : public LLMediaDataClient::Responder
     {
+        LOG_CLASS(Responder);
     public:
         Responder(const request_ptr_t &request)
             : LLMediaDataClient::Responder(request) {}
-		virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
-        virtual void result(const LLSD &content);
+    protected:
+        virtual void httpFailure();
+        virtual void httpSuccess();
     private:
         void mediaNavigateBounceBack();
     };
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 17311dd75e5663efc98bf5f5b5ceaff5acb1eb89..1469dbc346139bbc7dbcec9c4394eb81192e92b5 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -28,7 +28,7 @@
 
 #include "apr_pools.h"
 #include "apr_dso.h"
-#include "llhttpstatuscodes.h"
+#include "llhttpconstants.h"
 #include "llmeshrepository.h"
 
 #include "llagent.h"
@@ -202,6 +202,7 @@ U32	LLMeshRepoThread::sMaxConcurrentRequests = 1;
 
 class LLMeshHeaderResponder : public LLCurl::Responder
 {
+	LOG_CLASS(LLMeshHeaderResponder);
 public:
 	LLVolumeParams mMeshParams;
 	bool mProcessed;
@@ -230,14 +231,14 @@ class LLMeshHeaderResponder : public LLCurl::Responder
 		}
 	}
 
-	virtual void completedRaw(U32 status, const std::string& reason,
-							  const LLChannelDescriptors& channels,
+	virtual void completedRaw(const LLChannelDescriptors& channels,
 							  const LLIOPipe::buffer_ptr_t& buffer);
 
 };
 
 class LLMeshLODResponder : public LLCurl::Responder
 {
+	LOG_CLASS(LLMeshLODResponder);
 public:
 	LLVolumeParams mMeshParams;
 	S32 mLOD;
@@ -266,14 +267,14 @@ class LLMeshLODResponder : public LLCurl::Responder
 		}
 	}
 
-	virtual void completedRaw(U32 status, const std::string& reason,
-							  const LLChannelDescriptors& channels,
+	virtual void completedRaw(const LLChannelDescriptors& channels,
 							  const LLIOPipe::buffer_ptr_t& buffer);
 
 };
 
 class LLMeshSkinInfoResponder : public LLCurl::Responder
 {
+	LOG_CLASS(LLMeshSkinInfoResponder);
 public:
 	LLUUID mMeshID;
 	U32 mRequestedBytes;
@@ -291,14 +292,14 @@ class LLMeshSkinInfoResponder : public LLCurl::Responder
 		llassert(mProcessed);
 	}
 
-	virtual void completedRaw(U32 status, const std::string& reason,
-							  const LLChannelDescriptors& channels,
+	virtual void completedRaw(const LLChannelDescriptors& channels,
 							  const LLIOPipe::buffer_ptr_t& buffer);
 
 };
 
 class LLMeshDecompositionResponder : public LLCurl::Responder
 {
+	LOG_CLASS(LLMeshDecompositionResponder);
 public:
 	LLUUID mMeshID;
 	U32 mRequestedBytes;
@@ -316,14 +317,14 @@ class LLMeshDecompositionResponder : public LLCurl::Responder
 		llassert(mProcessed);
 	}
 
-	virtual void completedRaw(U32 status, const std::string& reason,
-							  const LLChannelDescriptors& channels,
+	virtual void completedRaw(const LLChannelDescriptors& channels,
 							  const LLIOPipe::buffer_ptr_t& buffer);
 
 };
 
 class LLMeshPhysicsShapeResponder : public LLCurl::Responder
 {
+	LOG_CLASS(LLMeshPhysicsShapeResponder);
 public:
 	LLUUID mMeshID;
 	U32 mRequestedBytes;
@@ -341,8 +342,7 @@ class LLMeshPhysicsShapeResponder : public LLCurl::Responder
 		llassert(mProcessed);
 	}
 
-	virtual void completedRaw(U32 status, const std::string& reason,
-							  const LLChannelDescriptors& channels,
+	virtual void completedRaw(const LLChannelDescriptors& channels,
 							  const LLIOPipe::buffer_ptr_t& buffer);
 
 };
@@ -398,6 +398,7 @@ void log_upload_error(S32 status, const LLSD& content, std::string stage, std::s
 
 class LLWholeModelFeeResponder: public LLCurl::Responder
 {
+	LOG_CLASS(LLWholeModelFeeResponder);
 	LLMeshUploadThread* mThread;
 	LLSD mModelData;
 	LLHandle<LLWholeModelFeeObserver> mObserverHandle;
@@ -421,21 +422,20 @@ class LLWholeModelFeeResponder: public LLCurl::Responder
 		}
 	}
 
-	virtual void completed(U32 status,
-						   const std::string& reason,
-						   const LLSD& content)
+protected:
+	virtual void httpCompleted()
 	{
-		LLSD cc = content;
+		LLSD cc = getContent();
 		if (gSavedSettings.getS32("MeshUploadFakeErrors")&1)
 		{
 			cc = llsd_from_file("fake_upload_error.xml");
 		}
-			
+
 		dump_llsd_to_file(cc,make_dump_name("whole_model_fee_response_",dump_num));
 
 		LLWholeModelFeeObserver* observer = mObserverHandle.get();
 
-		if (isGoodStatus(status) &&
+		if (isGoodStatus() &&
 			cc["state"].asString() == "upload")
 		{
 			mThread->mWholeModelUploadURL = cc["uploader"].asString();
@@ -448,13 +448,14 @@ class LLWholeModelFeeResponder: public LLCurl::Responder
 		}
 		else
 		{
-			llwarns << "fee request failed" << llendl;
+			llwarns << "fee request failed " << dumpResponse() << llendl;
+			S32 status = getStatus();
 			log_upload_error(status,cc,"fee",mModelData["name"]);
 			mThread->mWholeModelUploadURL = "";
 
 			if (observer)
 			{
-				observer->setModelPhysicsFeeErrorStatus(status, reason);
+				observer->setModelPhysicsFeeErrorStatus(status, getReason());
 			}
 		}
 	}
@@ -463,6 +464,7 @@ class LLWholeModelFeeResponder: public LLCurl::Responder
 
 class LLWholeModelUploadResponder: public LLCurl::Responder
 {
+	LOG_CLASS(LLWholeModelUploadResponder);
 	LLMeshUploadThread* mThread;
 	LLSD mModelData;
 	LLHandle<LLWholeModelUploadObserver> mObserverHandle;
@@ -487,11 +489,10 @@ class LLWholeModelUploadResponder: public LLCurl::Responder
 		}
 	}
 
-	virtual void completed(U32 status,
-						   const std::string& reason,
-						   const LLSD& content)
+protected:
+	virtual void httpCompleted()
 	{
-		LLSD cc = content;
+		LLSD cc = getContent();
 		if (gSavedSettings.getS32("MeshUploadFakeErrors")&2)
 		{
 			cc = llsd_from_file("fake_upload_error.xml");
@@ -503,7 +504,7 @@ class LLWholeModelUploadResponder: public LLCurl::Responder
 
 		// requested "mesh" asset type isn't actually the type
 		// of the resultant object, fix it up here.
-		if (isGoodStatus(status) &&
+		if (isGoodStatus() &&
 			cc["state"].asString() == "complete")
 		{
 			mModelData["asset_type"] = "object";
@@ -516,9 +517,9 @@ class LLWholeModelUploadResponder: public LLCurl::Responder
 		}
 		else
 		{
-			llwarns << "upload failed" << llendl;
+			llwarns << "upload failed " << dumpResponse() << llendl;
 			std::string model_name = mModelData["name"].asString();
-			log_upload_error(status,cc,"upload",model_name);
+			log_upload_error(getStatus(),cc,"upload",model_name);
 
 			if (observer)
 			{
@@ -807,7 +808,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
 
 			//reading from VFS failed for whatever reason, fetch from sim
 			std::vector<std::string> headers;
-			headers.push_back("Accept: application/octet-stream");
+			headers.push_back(HTTP_HEADER_ACCEPT + ": " + HTTP_CONTENT_OCTET_STREAM);
 
 			std::string http_url = constructUrl(mesh_id);
 			if (!http_url.empty())
@@ -889,7 +890,7 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
 
 			//reading from VFS failed for whatever reason, fetch from sim
 			std::vector<std::string> headers;
-			headers.push_back("Accept: application/octet-stream");
+			headers.push_back(HTTP_HEADER_ACCEPT + ": " + HTTP_CONTENT_OCTET_STREAM);
 
 			std::string http_url = constructUrl(mesh_id);
 			if (!http_url.empty())
@@ -970,7 +971,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
 
 			//reading from VFS failed for whatever reason, fetch from sim
 			std::vector<std::string> headers;
-			headers.push_back("Accept: application/octet-stream");
+			headers.push_back(HTTP_HEADER_ACCEPT + ": " + HTTP_CONTENT_OCTET_STREAM);
 
 			std::string http_url = constructUrl(mesh_id);
 			if (!http_url.empty())
@@ -1051,7 +1052,7 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, U32& c
 	//either cache entry doesn't exist or is corrupt, request header from simulator	
 	bool retval = true ;
 	std::vector<std::string> headers;
-	headers.push_back("Accept: application/octet-stream");
+	headers.push_back(HTTP_HEADER_ACCEPT + ": " + HTTP_CONTENT_OCTET_STREAM);
 
 	std::string http_url = constructUrl(mesh_params.getSculptID());
 	if (!http_url.empty())
@@ -1126,7 +1127,7 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod,
 
 			//reading from VFS failed for whatever reason, fetch from sim
 			std::vector<std::string> headers;
-			headers.push_back("Accept: application/octet-stream");
+			headers.push_back(HTTP_HEADER_ACCEPT + ": " + HTTP_CONTENT_OCTET_STREAM);
 
 			std::string http_url = constructUrl(mesh_id);
 			if (!http_url.empty())
@@ -1898,10 +1899,10 @@ void LLMeshRepository::cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header)
 
 }
 
-void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason,
-							  const LLChannelDescriptors& channels,
-							  const LLIOPipe::buffer_ptr_t& buffer)
+void LLMeshLODResponder::completedRaw(const LLChannelDescriptors& channels,
+									  const LLIOPipe::buffer_ptr_t& buffer)
 {
+	S32 status = getStatus();
 	mProcessed = true;
 	
 	// thread could have already be destroyed during logout
@@ -1912,14 +1913,15 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason,
 	
 	S32 data_size = buffer->countAfter(channels.in(), NULL);
 
+	// *TODO: What about 3xx redirect codes? What about status 400 (Bad Request)?
 	if (status < 200 || status > 400)
 	{
-		llwarns << status << ": " << reason << llendl;
+		llwarns << dumpResponse() << llendl;
 	}
 
 	if (data_size < mRequestedBytes)
 	{
-		if (status == 499 || status == 503)
+		if (status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE)
 		{ //timeout or service unavailable, try again
 			llwarns << "Timeout or service unavailable, retrying." << llendl;
 			LLMeshRepository::sHTTPRetryCount++;
@@ -1927,8 +1929,8 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason,
 		}
 		else
 		{
-			llassert(status == 499 || status == 503); //intentionally trigger a breakpoint
-			llwarns << "Unhandled status " << status << llendl;
+			llassert(status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint
+			llwarns << "Unhandled status " << dumpResponse() << llendl;
 		}
 		return;
 	}
@@ -1962,10 +1964,10 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason,
 	delete [] data;
 }
 
-void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason,
-							  const LLChannelDescriptors& channels,
-							  const LLIOPipe::buffer_ptr_t& buffer)
+void LLMeshSkinInfoResponder::completedRaw(const LLChannelDescriptors& channels,
+										   const LLIOPipe::buffer_ptr_t& buffer)
 {
+	S32 status = getStatus();
 	mProcessed = true;
 
 	// thread could have already be destroyed during logout
@@ -1976,14 +1978,15 @@ void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason
 
 	S32 data_size = buffer->countAfter(channels.in(), NULL);
 
+	// *TODO: What about 3xx redirect codes? What about status 400 (Bad Request)?
 	if (status < 200 || status > 400)
 	{
-		llwarns << status << ": " << reason << llendl;
+		llwarns << dumpResponse() << llendl;
 	}
 
 	if (data_size < mRequestedBytes)
 	{
-		if (status == 499 || status == 503)
+		if (status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE)
 		{ //timeout or service unavailable, try again
 			llwarns << "Timeout or service unavailable, retrying." << llendl;
 			LLMeshRepository::sHTTPRetryCount++;
@@ -1991,8 +1994,8 @@ void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason
 		}
 		else
 		{
-			llassert(status == 499 || status == 503); //intentionally trigger a breakpoint
-			llwarns << "Unhandled status " << status << llendl;
+			llassert(status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint
+			llwarns << "Unhandled status " << dumpResponse() << llendl;
 		}
 		return;
 	}
@@ -2026,10 +2029,10 @@ void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason
 	delete [] data;
 }
 
-void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& reason,
-							  const LLChannelDescriptors& channels,
-							  const LLIOPipe::buffer_ptr_t& buffer)
+void LLMeshDecompositionResponder::completedRaw(const LLChannelDescriptors& channels,
+												const LLIOPipe::buffer_ptr_t& buffer)
 {
+	S32 status = getStatus();
 	mProcessed = true;
 	
 	if( !gMeshRepo.mThread )
@@ -2039,14 +2042,15 @@ void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& r
 
 	S32 data_size = buffer->countAfter(channels.in(), NULL);
 
+	// *TODO: What about 3xx redirect codes? What about status 400 (Bad Request)?
 	if (status < 200 || status > 400)
 	{
-		llwarns << status << ": " << reason << llendl;
+		llwarns << dumpResponse() << llendl;
 	}
 
 	if (data_size < mRequestedBytes)
 	{
-		if (status == 499 || status == 503)
+		if (status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE)
 		{ //timeout or service unavailable, try again
 			llwarns << "Timeout or service unavailable, retrying." << llendl;
 			LLMeshRepository::sHTTPRetryCount++;
@@ -2054,8 +2058,8 @@ void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& r
 		}
 		else
 		{
-			llassert(status == 499 || status == 503); //intentionally trigger a breakpoint
-			llwarns << "Unhandled status " << status << llendl;
+			llassert(status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint
+			llwarns << "Unhandled status " << dumpResponse() << llendl;
 		}
 		return;
 	}
@@ -2089,10 +2093,10 @@ void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& r
 	delete [] data;
 }
 
-void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& reason,
-							  const LLChannelDescriptors& channels,
-							  const LLIOPipe::buffer_ptr_t& buffer)
+void LLMeshPhysicsShapeResponder::completedRaw(const LLChannelDescriptors& channels,
+											   const LLIOPipe::buffer_ptr_t& buffer)
 {
+	S32 status = getStatus();
 	mProcessed = true;
 
 	// thread could have already be destroyed during logout
@@ -2103,14 +2107,15 @@ void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& re
 
 	S32 data_size = buffer->countAfter(channels.in(), NULL);
 
+	// *TODO: What about 3xx redirect codes? What about status 400 (Bad Request)?
 	if (status < 200 || status > 400)
 	{
-		llwarns << status << ": " << reason << llendl;
+		llwarns << dumpResponse() << llendl;
 	}
 
 	if (data_size < mRequestedBytes)
 	{
-		if (status == 499 || status == 503)
+		if (status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE)
 		{ //timeout or service unavailable, try again
 			llwarns << "Timeout or service unavailable, retrying." << llendl;
 			LLMeshRepository::sHTTPRetryCount++;
@@ -2118,8 +2123,8 @@ void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& re
 		}
 		else
 		{
-			llassert(status == 499 || status == 503); //intentionally trigger a breakpoint
-			llwarns << "Unhandled status " << status << llendl;
+			llassert(status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint
+			llwarns << "Unhandled status " << dumpResponse() << llendl;
 		}
 		return;
 	}
@@ -2153,10 +2158,10 @@ void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& re
 	delete [] data;
 }
 
-void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,
-							  const LLChannelDescriptors& channels,
-							  const LLIOPipe::buffer_ptr_t& buffer)
+void LLMeshHeaderResponder::completedRaw(const LLChannelDescriptors& channels,
+										 const LLIOPipe::buffer_ptr_t& buffer)
 {
+	S32 status = getStatus();
 	mProcessed = true;
 
 	// thread could have already be destroyed during logout
@@ -2165,6 +2170,7 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,
 		return;
 	}
 
+	// *TODO: What about 3xx redirect codes? What about status 400 (Bad Request)?
 	if (status < 200 || status > 400)
 	{
 		//llwarns
@@ -2178,9 +2184,9 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,
 		// and (somewhat more optional than the others) retries
 		// again after some set period of time
 
-		llassert(status == 503 || status == 499);
+		llassert(status == HTTP_SERVICE_UNAVAILABLE || status == HTTP_INTERNAL_ERROR);
 
-		if (status == 503 || status == 499)
+		if (status == HTTP_SERVICE_UNAVAILABLE || status == HTTP_INTERNAL_ERROR)
 		{ //retry
 			llwarns << "Timeout or service unavailable, retrying." << llendl;
 			LLMeshRepository::sHTTPRetryCount++;
@@ -2192,7 +2198,7 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,
 		}
 		else
 		{
-			llwarns << "Unhandled status." << llendl;
+			llwarns << "Unhandled status " << dumpResponse() << llendl;
 		}
 	}
 
@@ -2214,9 +2220,7 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,
 
 	if (!success)
 	{
-		llwarns
-			<< "Unable to parse mesh header: "
-			<< status << ": " << reason << llendl;
+		llwarns << "Unable to parse mesh header: " << dumpResponse() << llendl;
 	}
 	else if (data && data_size > 0)
 	{
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index 862e4be203a5dea41b621fc98acf92b814b7bd2d..4f5e07c566f2ad78acc9797e737922eeee72ef4f 100644
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -95,15 +95,11 @@ class LLClassifiedClickMessageResponder : public LLHTTPClient::Responder
 {
 	LOG_CLASS(LLClassifiedClickMessageResponder);
 
-public:
+protected:
 	// If we get back an error (not found, etc...), handle it here
-	virtual void errorWithContent(
-		U32 status,
-		const std::string& reason,
-		const LLSD& content)
+	virtual void httpFailure()
 	{
-		llwarns << "Sending click message failed (" << status << "): [" << reason << "]" << llendl;
-		llwarns << "Content: [" << content << "]" << llendl;
+		llwarns << "Sending click message failed " << dumpResponse() << llendl;
 	}
 };
 
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index d6fccb97053ca4cb1c643db4e036b073918c0d31..21b58dfbbf20d0eba4b2d1c089805cbbb77b3cfa 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -529,7 +529,7 @@ void LLLandmarksPanel::setParcelID(const LLUUID& parcel_id)
 }
 
 // virtual
-void LLLandmarksPanel::setErrorStatus(U32 status, const std::string& reason)
+void LLLandmarksPanel::setErrorStatus(S32 status, const std::string& reason)
 {
 	llwarns << "Can't handle remote parcel request."<< " Http Status: "<< status << ". Reason : "<< reason<<llendl;
 }
diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h
index 4e787317baff74f987a7daaaa22dae61d80c04d9..14709b267e1a9cdb1d950f26f818e81ccc71f658 100644
--- a/indra/newview/llpanellandmarks.h
+++ b/indra/newview/llpanellandmarks.h
@@ -104,7 +104,7 @@ class LLLandmarksPanel : public LLPanelPlacesTab, LLRemoteParcelInfoObserver
 	//LLRemoteParcelInfoObserver interface
 	/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
 	/*virtual*/ void setParcelID(const LLUUID& parcel_id);
-	/*virtual*/ void setErrorStatus(U32 status, const std::string& reason);
+	/*virtual*/ void setErrorStatus(S32 status, const std::string& reason);
 	
 private:
 	void initFavoritesInventoryPanel();
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index bcb90bcb56662d219b2453909d61a81588a6437f..c4ba0979144c44266ef28ca46fc2afa05fd06c4c 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -437,7 +437,7 @@ void LLPanelLogin::showLoginWidgets()
 		sInstance->reshapeBrowser();
 		// *TODO: Append all the usual login parameters, like first_login=Y etc.
 		std::string splash_screen_url = LLGridManager::getInstance()->getLoginPage();
-		web_browser->navigateTo( splash_screen_url, "text/html" );
+		web_browser->navigateTo( splash_screen_url, HTTP_CONTENT_TEXT_HTML );
 		LLUICtrl* username_combo = sInstance->getChild<LLUICtrl>("username_combo");
 		username_combo->setFocus(TRUE);
 	}
@@ -791,7 +791,7 @@ void LLPanelLogin::loadLoginPage()
 	if (web_browser->getCurrentNavUrl() != login_uri.asString())
 	{
 		LL_DEBUGS("AppInit") << "loading:    " << login_uri << LL_ENDL;
-		web_browser->navigateTo( login_uri.asString(), "text/html" );
+		web_browser->navigateTo( login_uri.asString(), HTTP_CONTENT_TEXT_HTML );
 	}
 }
 
diff --git a/indra/newview/llpanelpick.h b/indra/newview/llpanelpick.h
index 3c1f14759c82b23974db4f85da22c5019748b15b..7a8bd66fcfe2420a503b3be2b8a107339ed9a62e 100644
--- a/indra/newview/llpanelpick.h
+++ b/indra/newview/llpanelpick.h
@@ -86,7 +86,7 @@ class LLPanelPickInfo : public LLPanel, public LLAvatarPropertiesObserver, LLRem
 	//This stuff we got from LLRemoteParcelObserver, in the last one we intentionally do nothing
 	/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
 	/*virtual*/ void setParcelID(const LLUUID& parcel_id) { mParcelId = parcel_id; }
-	/*virtual*/ void setErrorStatus(U32 status, const std::string& reason) {};
+	/*virtual*/ void setErrorStatus(S32 status, const std::string& reason) {};
 
 protected:
 
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index 4ae0c0eb1252c7c595b47333f3f75c89d61bb335..4e7c5f6ed2912e64bce73898d280bd8475f76d67 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -169,15 +169,15 @@ void LLPanelPlaceInfo::displayParcelInfo(const LLUUID& region_id,
 }
 
 // virtual
-void LLPanelPlaceInfo::setErrorStatus(U32 status, const std::string& reason)
+void LLPanelPlaceInfo::setErrorStatus(S32 status, const std::string& reason)
 {
 	// We only really handle 404 and 499 errors
 	std::string error_text;
-	if(status == 404)
+	if(status == HTTP_NOT_FOUND)
 	{
 		error_text = getString("server_error_text");
 	}
-	else if(status == 499)
+	else if(status == HTTP_INTERNAL_ERROR)
 	{
 		error_text = getString("server_forbidden_text");
 	}
diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h
index 64f0b6b5503898e84746a10d35b5cfc406af52a2..30327378eff8c09a9d382e83ff3f7ca0881878e3 100644
--- a/indra/newview/llpanelplaceinfo.h
+++ b/indra/newview/llpanelplaceinfo.h
@@ -86,7 +86,7 @@ class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver
 	void displayParcelInfo(const LLUUID& region_id,
 						   const LLVector3d& pos_global);
 
-	/*virtual*/ void setErrorStatus(U32 status, const std::string& reason);
+	/*virtual*/ void setErrorStatus(S32 status, const std::string& reason);
 
 	/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
 
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 6c2a01fc82fdad1bbd1f66abf38ea3e3d9c52f45..730df2ea238f642b2d1cae352e290c76abb58dc4 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -217,7 +217,7 @@ class LLPlacesRemoteParcelInfoObserver : public LLRemoteParcelInfoObserver
 			LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(parcel_id);
 		}
 	}
-	/*virtual*/ void setErrorStatus(U32 status, const std::string& reason)
+	/*virtual*/ void setErrorStatus(S32 status, const std::string& reason)
 	{
 		llerrs << "Can't complete remote parcel request. Http Status: "
 			   << status << ". Reason : " << reason << llendl;
diff --git a/indra/newview/llpathfindingmanager.cpp b/indra/newview/llpathfindingmanager.cpp
index c277359133285f460f0000c587b14118ff9dd854..a9c755de35e63032be0a2dabd9a065a14a01fdcf 100644
--- a/indra/newview/llpathfindingmanager.cpp
+++ b/indra/newview/llpathfindingmanager.cpp
@@ -103,17 +103,16 @@ LLHTTPRegistration<LLAgentStateChangeNode> gHTTPRegistrationAgentStateChangeNode
 
 class NavMeshStatusResponder : public LLHTTPClient::Responder
 {
+	LOG_CLASS(NavMeshStatusResponder);
 public:
-	NavMeshStatusResponder(const std::string &pCapabilityURL, LLViewerRegion *pRegion, bool pIsGetStatusOnly);
+	NavMeshStatusResponder(LLViewerRegion *pRegion, bool pIsGetStatusOnly);
 	virtual ~NavMeshStatusResponder();
 
-	virtual void result(const LLSD &pContent);
-	virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);
-
 protected:
+	virtual void httpSuccess();
+	virtual void httpFailure();
 
 private:
-	std::string    mCapabilityURL;
 	LLViewerRegion *mRegion;
 	LLUUID         mRegionUUID;
 	bool           mIsGetStatusOnly;
@@ -125,17 +124,16 @@ class NavMeshStatusResponder : public LLHTTPClient::Responder
 
 class NavMeshResponder : public LLHTTPClient::Responder
 {
+    LOG_CLASS(NavMeshResponder);
 public:
-	NavMeshResponder(const std::string &pCapabilityURL, U32 pNavMeshVersion, LLPathfindingNavMeshPtr pNavMeshPtr);
+	NavMeshResponder(U32 pNavMeshVersion, LLPathfindingNavMeshPtr pNavMeshPtr);
 	virtual ~NavMeshResponder();
 
-	virtual void result(const LLSD &pContent);
-	virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);
-
 protected:
+	virtual void httpSuccess();
+	virtual void httpFailure();
 
 private:
-	std::string             mCapabilityURL;
 	U32                     mNavMeshVersion;
 	LLPathfindingNavMeshPtr mNavMeshPtr;
 };
@@ -146,17 +144,14 @@ class NavMeshResponder : public LLHTTPClient::Responder
 
 class AgentStateResponder : public LLHTTPClient::Responder
 {
+	LOG_CLASS(AgentStateResponder);
 public:
-	AgentStateResponder(const std::string &pCapabilityURL);
+	AgentStateResponder();
 	virtual ~AgentStateResponder();
 
-	virtual void result(const LLSD &pContent);
-	virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);
-
 protected:
-
-private:
-	std::string mCapabilityURL;
+	virtual void httpSuccess();
+	virtual void httpFailure();
 };
 
 
@@ -165,17 +160,16 @@ class AgentStateResponder : public LLHTTPClient::Responder
 //---------------------------------------------------------------------------
 class NavMeshRebakeResponder : public LLHTTPClient::Responder
 {
+	LOG_CLASS(NavMeshRebakeResponder);
 public:
-	NavMeshRebakeResponder(const std::string &pCapabilityURL, LLPathfindingManager::rebake_navmesh_callback_t pRebakeNavMeshCallback);
+	NavMeshRebakeResponder(LLPathfindingManager::rebake_navmesh_callback_t pRebakeNavMeshCallback);
 	virtual ~NavMeshRebakeResponder();
 
-	virtual void result(const LLSD &pContent);
-	virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);
-
 protected:
+	virtual void httpSuccess();
+	virtual void httpFailure();
 
 private:
-	std::string                                     mCapabilityURL;
 	LLPathfindingManager::rebake_navmesh_callback_t mRebakeNavMeshCallback;
 };
 
@@ -190,11 +184,9 @@ class LinksetsResponder
 	virtual ~LinksetsResponder();
 
 	void handleObjectLinksetsResult(const LLSD &pContent);
-	void handleObjectLinksetsError(U32 pStatus, const std::string &pReason, 
-								   const LLSD& pContent, const std::string &pURL);
+	void handleObjectLinksetsError();
 	void handleTerrainLinksetsResult(const LLSD &pContent);
-	void handleTerrainLinksetsError(U32 pStatus, const std::string &pReason,
-									const LLSD& pContent, const std::string &pURL);
+	void handleTerrainLinksetsError();
 
 protected:
 
@@ -227,17 +219,16 @@ typedef boost::shared_ptr<LinksetsResponder> LinksetsResponderPtr;
 
 class ObjectLinksetsResponder : public LLHTTPClient::Responder
 {
+	LOG_CLASS(ObjectLinksetsResponder);
 public:
-	ObjectLinksetsResponder(const std::string &pCapabilityURL, LinksetsResponderPtr pLinksetsResponsderPtr);
+	ObjectLinksetsResponder(LinksetsResponderPtr pLinksetsResponsderPtr);
 	virtual ~ObjectLinksetsResponder();
 
-	virtual void result(const LLSD &pContent);
-	virtual void errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent);
-
 protected:
+	virtual void httpSuccess();
+	virtual void httpFailure();
 
 private:
-	std::string          mCapabilityURL;
 	LinksetsResponderPtr mLinksetsResponsderPtr;
 };
 
@@ -247,17 +238,16 @@ class ObjectLinksetsResponder : public LLHTTPClient::Responder
 
 class TerrainLinksetsResponder : public LLHTTPClient::Responder
 {
+	LOG_CLASS(TerrainLinksetsResponder);
 public:
-	TerrainLinksetsResponder(const std::string &pCapabilityURL, LinksetsResponderPtr pLinksetsResponsderPtr);
+	TerrainLinksetsResponder(LinksetsResponderPtr pLinksetsResponsderPtr);
 	virtual ~TerrainLinksetsResponder();
 
-	virtual void result(const LLSD &pContent);
-	virtual void errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent);
-
 protected:
+	virtual void httpSuccess();
+	virtual void httpFailure();
 
 private:
-	std::string          mCapabilityURL;
 	LinksetsResponderPtr mLinksetsResponsderPtr;
 };
 
@@ -267,17 +257,16 @@ class TerrainLinksetsResponder : public LLHTTPClient::Responder
 
 class CharactersResponder : public LLHTTPClient::Responder
 {
+	LOG_CLASS(TerrainLinksetsResponder);
 public:
-	CharactersResponder(const std::string &pCapabilityURL, LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::object_request_callback_t pCharactersCallback);
+	CharactersResponder(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::object_request_callback_t pCharactersCallback);
 	virtual ~CharactersResponder();
 
-	virtual void result(const LLSD &pContent);
-	virtual void errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent);
-
 protected:
+	virtual void httpSuccess();
+	virtual void httpFailure();
 
 private:
-	std::string                                     mCapabilityURL;
 	LLPathfindingManager::request_id_t              mRequestId;
 	LLPathfindingManager::object_request_callback_t mCharactersCallback;
 };
@@ -364,7 +353,7 @@ void LLPathfindingManager::requestGetNavMeshForRegion(LLViewerRegion *pRegion, b
 		std::string navMeshStatusURL = getNavMeshStatusURLForRegion(pRegion);
 		llassert(!navMeshStatusURL.empty());
 		navMeshPtr->handleNavMeshCheckVersion();
-		LLHTTPClient::ResponderPtr navMeshStatusResponder = new NavMeshStatusResponder(navMeshStatusURL, pRegion, pIsGetStatusOnly);
+		LLHTTPClient::ResponderPtr navMeshStatusResponder = new NavMeshStatusResponder(pRegion, pIsGetStatusOnly);
 		LLHTTPClient::get(navMeshStatusURL, navMeshStatusResponder);
 	}
 }
@@ -398,12 +387,12 @@ void LLPathfindingManager::requestGetLinksets(request_id_t pRequestId, object_re
 			bool doRequestTerrain = isAllowViewTerrainProperties();
 			LinksetsResponderPtr linksetsResponderPtr(new LinksetsResponder(pRequestId, pLinksetsCallback, true, doRequestTerrain));
 
-			LLHTTPClient::ResponderPtr objectLinksetsResponder = new ObjectLinksetsResponder(objectLinksetsURL, linksetsResponderPtr);
+			LLHTTPClient::ResponderPtr objectLinksetsResponder = new ObjectLinksetsResponder(linksetsResponderPtr);
 			LLHTTPClient::get(objectLinksetsURL, objectLinksetsResponder);
 
 			if (doRequestTerrain)
 			{
-				LLHTTPClient::ResponderPtr terrainLinksetsResponder = new TerrainLinksetsResponder(terrainLinksetsURL, linksetsResponderPtr);
+				LLHTTPClient::ResponderPtr terrainLinksetsResponder = new TerrainLinksetsResponder(linksetsResponderPtr);
 				LLHTTPClient::get(terrainLinksetsURL, terrainLinksetsResponder);
 			}
 		}
@@ -447,13 +436,13 @@ void LLPathfindingManager::requestSetLinksets(request_id_t pRequestId, const LLP
 
 			if (!objectPostData.isUndefined())
 			{
-				LLHTTPClient::ResponderPtr objectLinksetsResponder = new ObjectLinksetsResponder(objectLinksetsURL, linksetsResponderPtr);
+				LLHTTPClient::ResponderPtr objectLinksetsResponder = new ObjectLinksetsResponder(linksetsResponderPtr);
 				LLHTTPClient::put(objectLinksetsURL, objectPostData, objectLinksetsResponder);
 			}
 
 			if (!terrainPostData.isUndefined())
 			{
-				LLHTTPClient::ResponderPtr terrainLinksetsResponder = new TerrainLinksetsResponder(terrainLinksetsURL, linksetsResponderPtr);
+				LLHTTPClient::ResponderPtr terrainLinksetsResponder = new TerrainLinksetsResponder(linksetsResponderPtr);
 				LLHTTPClient::put(terrainLinksetsURL, terrainPostData, terrainLinksetsResponder);
 			}
 		}
@@ -486,7 +475,7 @@ void LLPathfindingManager::requestGetCharacters(request_id_t pRequestId, object_
 		{
 			pCharactersCallback(pRequestId, kRequestStarted, emptyCharacterListPtr);
 
-			LLHTTPClient::ResponderPtr charactersResponder = new CharactersResponder(charactersURL, pRequestId, pCharactersCallback);
+			LLHTTPClient::ResponderPtr charactersResponder = new CharactersResponder(pRequestId, pCharactersCallback);
 			LLHTTPClient::get(charactersURL, charactersResponder);
 		}
 	}
@@ -519,7 +508,7 @@ void LLPathfindingManager::requestGetAgentState()
 		{
 			std::string agentStateURL = getAgentStateURLForRegion(currentRegion);
 			llassert(!agentStateURL.empty());
-			LLHTTPClient::ResponderPtr responder = new AgentStateResponder(agentStateURL);
+			LLHTTPClient::ResponderPtr responder = new AgentStateResponder();
 			LLHTTPClient::get(agentStateURL, responder);
 		}
 	}
@@ -543,7 +532,7 @@ void LLPathfindingManager::requestRebakeNavMesh(rebake_navmesh_callback_t pRebak
 		llassert(!navMeshStatusURL.empty());
 		LLSD postData;			
 		postData["command"] = "rebuild";
-		LLHTTPClient::ResponderPtr responder = new NavMeshRebakeResponder(navMeshStatusURL, pRebakeNavMeshCallback);
+		LLHTTPClient::ResponderPtr responder = new NavMeshRebakeResponder(pRebakeNavMeshCallback);
 		LLHTTPClient::post(navMeshStatusURL, postData, responder);
 	}
 }
@@ -565,7 +554,7 @@ void LLPathfindingManager::sendRequestGetNavMeshForRegion(LLPathfindingNavMeshPt
 		else
 		{
 			navMeshPtr->handleNavMeshStart(pNavMeshStatus);
-			LLHTTPClient::ResponderPtr responder = new NavMeshResponder(navMeshURL, pNavMeshStatus.getVersion(), navMeshPtr);
+			LLHTTPClient::ResponderPtr responder = new NavMeshResponder(pNavMeshStatus.getVersion(), navMeshPtr);
 
 			LLSD postData;
 			LLHTTPClient::post(navMeshURL, postData, responder);
@@ -779,9 +768,8 @@ void LLAgentStateChangeNode::post(ResponsePtr pResponse, const LLSD &pContext, c
 // NavMeshStatusResponder
 //---------------------------------------------------------------------------
 
-NavMeshStatusResponder::NavMeshStatusResponder(const std::string &pCapabilityURL, LLViewerRegion *pRegion, bool pIsGetStatusOnly)
+NavMeshStatusResponder::NavMeshStatusResponder(LLViewerRegion *pRegion, bool pIsGetStatusOnly)
 	: LLHTTPClient::Responder(),
-	mCapabilityURL(pCapabilityURL),
 	mRegion(pRegion),
 	mRegionUUID(),
 	mIsGetStatusOnly(pIsGetStatusOnly)
@@ -796,15 +784,15 @@ NavMeshStatusResponder::~NavMeshStatusResponder()
 {
 }
 
-void NavMeshStatusResponder::result(const LLSD &pContent)
+void NavMeshStatusResponder::httpSuccess()
 {
-	LLPathfindingNavMeshStatus navMeshStatus(mRegionUUID, pContent);
+	LLPathfindingNavMeshStatus navMeshStatus(mRegionUUID, getContent());
 	LLPathfindingManager::getInstance()->handleNavMeshStatusRequest(navMeshStatus, mRegion, mIsGetStatusOnly);
 }
 
-void NavMeshStatusResponder::errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent)
+void NavMeshStatusResponder::httpFailure()
 {
-	llwarns << "NavMeshStatusResponder error [status:" << pStatus << "]: " << pContent << llendl;
+	llwarns << dumpResponse() << llendl;
 	LLPathfindingNavMeshStatus navMeshStatus(mRegionUUID);
 	LLPathfindingManager::getInstance()->handleNavMeshStatusRequest(navMeshStatus, mRegion, mIsGetStatusOnly);
 }
@@ -813,9 +801,8 @@ void NavMeshStatusResponder::errorWithContent(U32 pStatus, const std::string& pR
 // NavMeshResponder
 //---------------------------------------------------------------------------
 
-NavMeshResponder::NavMeshResponder(const std::string &pCapabilityURL, U32 pNavMeshVersion, LLPathfindingNavMeshPtr pNavMeshPtr)
+NavMeshResponder::NavMeshResponder(U32 pNavMeshVersion, LLPathfindingNavMeshPtr pNavMeshPtr)
 	: LLHTTPClient::Responder(),
-	mCapabilityURL(pCapabilityURL),
 	mNavMeshVersion(pNavMeshVersion),
 	mNavMeshPtr(pNavMeshPtr)
 {
@@ -825,23 +812,23 @@ NavMeshResponder::~NavMeshResponder()
 {
 }
 
-void NavMeshResponder::result(const LLSD &pContent)
+void NavMeshResponder::httpSuccess()
 {
-	mNavMeshPtr->handleNavMeshResult(pContent, mNavMeshVersion);
+	mNavMeshPtr->handleNavMeshResult(getContent(), mNavMeshVersion);
 }
 
-void NavMeshResponder::errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent)
+void NavMeshResponder::httpFailure()
 {
-	mNavMeshPtr->handleNavMeshError(pStatus, pReason, pContent, mCapabilityURL, mNavMeshVersion);
+	llwarns << dumpResponse() << llendl;
+	mNavMeshPtr->handleNavMeshError(mNavMeshVersion);
 }
 
 //---------------------------------------------------------------------------
 // AgentStateResponder
 //---------------------------------------------------------------------------
 
-AgentStateResponder::AgentStateResponder(const std::string &pCapabilityURL)
+AgentStateResponder::AgentStateResponder()
 : LLHTTPClient::Responder()
-, mCapabilityURL(pCapabilityURL)
 {
 }
 
@@ -849,17 +836,18 @@ AgentStateResponder::~AgentStateResponder()
 {
 }
 
-void AgentStateResponder::result(const LLSD &pContent)
+void AgentStateResponder::httpSuccess()
 {
+	const LLSD& pContent = getContent();
 	llassert(pContent.has(AGENT_STATE_CAN_REBAKE_REGION_FIELD));
 	llassert(pContent.get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).isBoolean());
 	BOOL canRebakeRegion = pContent.get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).asBoolean();
 	LLPathfindingManager::getInstance()->handleAgentState(canRebakeRegion);
 }
 
-void AgentStateResponder::errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent)
+void AgentStateResponder::httpFailure()
 {
-	llwarns << "AgentStateResponder error [status:" << pStatus << "]: " << pContent << llendl;
+	llwarns << dumpResponse() << llendl;
 	LLPathfindingManager::getInstance()->handleAgentState(FALSE);
 }
 
@@ -867,9 +855,8 @@ void AgentStateResponder::errorWithContent(U32 pStatus, const std::string &pReas
 //---------------------------------------------------------------------------
 // navmesh rebake responder
 //---------------------------------------------------------------------------
-NavMeshRebakeResponder::NavMeshRebakeResponder(const std::string &pCapabilityURL, LLPathfindingManager::rebake_navmesh_callback_t pRebakeNavMeshCallback)
+NavMeshRebakeResponder::NavMeshRebakeResponder(LLPathfindingManager::rebake_navmesh_callback_t pRebakeNavMeshCallback)
 	: LLHTTPClient::Responder(),
-	mCapabilityURL(pCapabilityURL),
 	mRebakeNavMeshCallback(pRebakeNavMeshCallback)
 {
 }
@@ -878,14 +865,14 @@ NavMeshRebakeResponder::~NavMeshRebakeResponder()
 {
 }
 
-void NavMeshRebakeResponder::result(const LLSD &pContent)
+void NavMeshRebakeResponder::httpSuccess()
 {
 	mRebakeNavMeshCallback(true);
 }
 
-void NavMeshRebakeResponder::errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent)
+void NavMeshRebakeResponder::httpFailure()
 {
-	llwarns << "NavMeshRebakeResponder error [status:" << pStatus << "]: " << pContent << llendl;
+	llwarns << dumpResponse() << llendl;
 	mRebakeNavMeshCallback(false);
 }
 
@@ -918,11 +905,8 @@ void LinksetsResponder::handleObjectLinksetsResult(const LLSD &pContent)
 	}
 }
 
-void LinksetsResponder::handleObjectLinksetsError(U32 pStatus, const std::string &pReason,
-												 const LLSD& pContent, const std::string &pURL)
+void LinksetsResponder::handleObjectLinksetsError()
 {
-	llwarns << "LinksetsResponder object linksets error with request to URL '" << pURL << "' [status:"
-			<< pStatus << "]: " << pContent << llendl;
 	mObjectMessagingState = kReceivedError;
 	if (mTerrainMessagingState != kWaiting)
 	{
@@ -941,11 +925,8 @@ void LinksetsResponder::handleTerrainLinksetsResult(const LLSD &pContent)
 	}
 }
 
-void LinksetsResponder::handleTerrainLinksetsError(U32 pStatus, const std::string &pReason,
-												   const LLSD& pContent, const std::string &pURL)
+void LinksetsResponder::handleTerrainLinksetsError()
 {
-	llwarns << "LinksetsResponder terrain linksets error with request to URL '" << pURL << "' [status:"
-			<< pStatus << "]: " << pContent << llendl;
 	mTerrainMessagingState = kReceivedError;
 	if (mObjectMessagingState != kWaiting)
 	{
@@ -979,9 +960,8 @@ void LinksetsResponder::sendCallback()
 // ObjectLinksetsResponder
 //---------------------------------------------------------------------------
 
-ObjectLinksetsResponder::ObjectLinksetsResponder(const std::string &pCapabilityURL, LinksetsResponderPtr pLinksetsResponsderPtr)
+ObjectLinksetsResponder::ObjectLinksetsResponder(LinksetsResponderPtr pLinksetsResponsderPtr)
 	: LLHTTPClient::Responder(),
-	mCapabilityURL(pCapabilityURL),
 	mLinksetsResponsderPtr(pLinksetsResponsderPtr)
 {
 }
@@ -990,23 +970,23 @@ ObjectLinksetsResponder::~ObjectLinksetsResponder()
 {
 }
 
-void ObjectLinksetsResponder::result(const LLSD &pContent)
+void ObjectLinksetsResponder::httpSuccess()
 {
-	mLinksetsResponsderPtr->handleObjectLinksetsResult(pContent);
+	mLinksetsResponsderPtr->handleObjectLinksetsResult(getContent());
 }
 
-void ObjectLinksetsResponder::errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent)
+void ObjectLinksetsResponder::httpFailure()
 {
-	mLinksetsResponsderPtr->handleObjectLinksetsError(pStatus, pReason, pContent, mCapabilityURL);
+	llwarns << dumpResponse() << llendl;
+	mLinksetsResponsderPtr->handleObjectLinksetsError();
 }
 
 //---------------------------------------------------------------------------
 // TerrainLinksetsResponder
 //---------------------------------------------------------------------------
 
-TerrainLinksetsResponder::TerrainLinksetsResponder(const std::string &pCapabilityURL, LinksetsResponderPtr pLinksetsResponsderPtr)
+TerrainLinksetsResponder::TerrainLinksetsResponder(LinksetsResponderPtr pLinksetsResponsderPtr)
 	: LLHTTPClient::Responder(),
-	mCapabilityURL(pCapabilityURL),
 	mLinksetsResponsderPtr(pLinksetsResponsderPtr)
 {
 }
@@ -1015,23 +995,23 @@ TerrainLinksetsResponder::~TerrainLinksetsResponder()
 {
 }
 
-void TerrainLinksetsResponder::result(const LLSD &pContent)
+void TerrainLinksetsResponder::httpSuccess()
 {
-	mLinksetsResponsderPtr->handleTerrainLinksetsResult(pContent);
+	mLinksetsResponsderPtr->handleTerrainLinksetsResult(getContent());
 }
 
-void TerrainLinksetsResponder::errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent)
+void TerrainLinksetsResponder::httpFailure()
 {
-	mLinksetsResponsderPtr->handleTerrainLinksetsError(pStatus, pReason, pContent, mCapabilityURL);
+	llwarns << dumpResponse() << llendl;
+	mLinksetsResponsderPtr->handleTerrainLinksetsError();
 }
 
 //---------------------------------------------------------------------------
 // CharactersResponder
 //---------------------------------------------------------------------------
 
-CharactersResponder::CharactersResponder(const std::string &pCapabilityURL, LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::object_request_callback_t pCharactersCallback)
+CharactersResponder::CharactersResponder(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::object_request_callback_t pCharactersCallback)
 	: LLHTTPClient::Responder(),
-	mCapabilityURL(pCapabilityURL),
 	mRequestId(pRequestId),
 	mCharactersCallback(pCharactersCallback)
 {
@@ -1041,15 +1021,15 @@ CharactersResponder::~CharactersResponder()
 {
 }
 
-void CharactersResponder::result(const LLSD &pContent)
+void CharactersResponder::httpSuccess()
 {
-	LLPathfindingObjectListPtr characterListPtr = LLPathfindingObjectListPtr(new LLPathfindingCharacterList(pContent));
+	LLPathfindingObjectListPtr characterListPtr = LLPathfindingObjectListPtr(new LLPathfindingCharacterList(getContent()));
 	mCharactersCallback(mRequestId, LLPathfindingManager::kRequestCompleted, characterListPtr);
 }
 
-void CharactersResponder::errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent)
+void CharactersResponder::httpFailure()
 {
-	llwarns << "CharactersResponder error [status:" << pStatus << "]: " << pContent << llendl;
+	llwarns << dumpResponse() << llendl;
 
 	LLPathfindingObjectListPtr characterListPtr =  LLPathfindingObjectListPtr(new LLPathfindingCharacterList());
 	mCharactersCallback(mRequestId, LLPathfindingManager::kRequestError, characterListPtr);
diff --git a/indra/newview/llpathfindingnavmesh.cpp b/indra/newview/llpathfindingnavmesh.cpp
index 0c23e5ac923785ae99a64625f321ad6b4af2bf1e..555105cf409a5ff6b3d36579bd5bbcf7c872bea2 100644
--- a/indra/newview/llpathfindingnavmesh.cpp
+++ b/indra/newview/llpathfindingnavmesh.cpp
@@ -184,10 +184,8 @@ void LLPathfindingNavMesh::handleNavMeshError()
 	setRequestStatus(kNavMeshRequestError);
 }
 
-void LLPathfindingNavMesh::handleNavMeshError(U32 pStatus, const std::string &pReason, const LLSD& pContent, const std::string &pURL, U32 pNavMeshVersion)
+void LLPathfindingNavMesh::handleNavMeshError(U32 pNavMeshVersion)
 {
-	llwarns << "LLPathfindingNavMesh error with request to URL '" << pURL << "' [status:"
-			<< pStatus << "]: " << pContent << llendl;
 	if (mNavMeshStatus.getVersion() == pNavMeshVersion)
 	{
 		handleNavMeshError();
diff --git a/indra/newview/llpathfindingnavmesh.h b/indra/newview/llpathfindingnavmesh.h
index b872ccad7cbd24235889a427beb36b512cd2c292..87f32b8d56487245b7ff0ba0d890845b483cfb4a 100644
--- a/indra/newview/llpathfindingnavmesh.h
+++ b/indra/newview/llpathfindingnavmesh.h
@@ -74,7 +74,7 @@ class LLPathfindingNavMesh
 	void handleNavMeshResult(const LLSD &pContent, U32 pNavMeshVersion);
 	void handleNavMeshNotEnabled();
 	void handleNavMeshError();
-	void handleNavMeshError(U32 pStatus, const std::string &pReason, const LLSD& pContent, const std::string &pURL, U32 pNavMeshVersion);
+	void handleNavMeshError(U32 pNavMeshVersion);
 
 protected:
 
diff --git a/indra/newview/llproductinforequest.cpp b/indra/newview/llproductinforequest.cpp
index 1390000fc506eb1bbba570224824e0283f52fe64..94a6389f8a7202e8d16539a9561507a2422f1e48 100644
--- a/indra/newview/llproductinforequest.cpp
+++ b/indra/newview/llproductinforequest.cpp
@@ -35,18 +35,24 @@
 
 class LLProductInfoRequestResponder : public LLHTTPClient::Responder
 {
-public:
+	LOG_CLASS(LLProductInfoRequestResponder);
+private:
 	//If we get back a normal response, handle it here
-	virtual void result(const LLSD& content)
+	/* virtual */ void httpSuccess()
 	{
-		LLProductInfoRequestManager::instance().setSkuDescriptions(content);
+		const LLSD& content = getContent();
+		if (!content.isArray())
+		{
+			failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+			return;
+		}
+		LLProductInfoRequestManager::instance().setSkuDescriptions(getContent());
 	}
 
 	//If we get back an error (not found, etc...), handle it here
-	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+	/* virtual */ void httpFailure()
 	{
-		llwarns << "LLProductInfoRequest error [status:"
-				<< status << ":] " << content << llendl;
+		llwarns << dumpResponse() << llendl;
 	}
 };
 
diff --git a/indra/newview/llremoteparcelrequest.cpp b/indra/newview/llremoteparcelrequest.cpp
index 500dec7ee5841878bfbddb2857f9a590c6b847b9..7418bbf615035d1ad889b2eb2c08f7b611d57083 100644
--- a/indra/newview/llremoteparcelrequest.cpp
+++ b/indra/newview/llremoteparcelrequest.cpp
@@ -47,9 +47,15 @@ LLRemoteParcelRequestResponder::LLRemoteParcelRequestResponder(LLHandle<LLRemote
 
 //If we get back a normal response, handle it here
 //virtual
-void LLRemoteParcelRequestResponder::result(const LLSD& content)
+void LLRemoteParcelRequestResponder::httpSuccess()
 {
-	LLUUID parcel_id = content["parcel_id"];
+	const LLSD& content = getContent();
+	if (!content.isMap() || !content.has("parcel_id"))
+	{
+		failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+		return;
+	}
+	LLUUID parcel_id = getContent()["parcel_id"];
 
 	// Panel inspecting the information may be closed and destroyed
 	// before this response is received.
@@ -62,17 +68,16 @@ void LLRemoteParcelRequestResponder::result(const LLSD& content)
 
 //If we get back an error (not found, etc...), handle it here
 //virtual
-void LLRemoteParcelRequestResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+void LLRemoteParcelRequestResponder::httpFailure()
 {
-	llwarns << "LLRemoteParcelRequest error [status:"
-			<< status << "]: " << content << llendl;
+	llwarns << dumpResponse() << llendl;
 
 	// Panel inspecting the information may be closed and destroyed
 	// before this response is received.
 	LLRemoteParcelInfoObserver* observer = mObserverHandle.get();
 	if (observer)
 	{
-		observer->setErrorStatus(status, reason);
+		observer->setErrorStatus(getStatus(), getReason());
 	}
 }
 
diff --git a/indra/newview/llremoteparcelrequest.h b/indra/newview/llremoteparcelrequest.h
index b87056573b1bfea0ea4753f9a220b57b83b11763..0f8ae41d76756965347c1c46e59f4e1b0b00f84c 100644
--- a/indra/newview/llremoteparcelrequest.h
+++ b/indra/newview/llremoteparcelrequest.h
@@ -37,16 +37,17 @@ class LLRemoteParcelInfoObserver;
 
 class LLRemoteParcelRequestResponder : public LLHTTPClient::Responder
 {
+	LOG_CLASS(LLRemoteParcelRequestResponder);
 public:
 	LLRemoteParcelRequestResponder(LLHandle<LLRemoteParcelInfoObserver> observer_handle);
 
+private:
 	//If we get back a normal response, handle it here
-	/*virtual*/ void result(const LLSD& content);
+	/*virtual*/ void httpSuccess();
 
 	//If we get back an error (not found, etc...), handle it here
-	/*virtual*/ void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
+	/*virtual*/ void httpFailure();
 
-protected:
 	LLHandle<LLRemoteParcelInfoObserver> mObserverHandle;
 };
 
@@ -78,7 +79,7 @@ class LLRemoteParcelInfoObserver
 	virtual ~LLRemoteParcelInfoObserver() {}
 	virtual void processParcelInfo(const LLParcelData& parcel_data) = 0;
 	virtual void setParcelID(const LLUUID& parcel_id) = 0;
-	virtual void setErrorStatus(U32 status, const std::string& reason) = 0;
+	virtual void setErrorStatus(S32 status, const std::string& reason) = 0;
 	LLHandle<LLRemoteParcelInfoObserver>	getObserverHandle() const { return mObserverHandle; }
 
 protected:
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 890bc0f42d45afcdd1266ed831578ad5ac30a294..1065b744b9990620d8cc2dfc20073efac52375f7 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -720,21 +720,23 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update)
 
 class ModerationResponder : public LLHTTPClient::Responder
 {
+	LOG_CLASS(ModerationResponder);
 public:
 	ModerationResponder(const LLUUID& session_id)
 	{
 		mSessionID = session_id;
 	}
 
-	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+protected:
+	virtual void httpFailure()
 	{
-		llwarns << "ModerationResponder error [status:" << status << "]: " << content << llendl;
+		llwarns << dumpResponse() << llendl;
 
 		if ( gIMMgr )
 		{
 			//403 == you're not a mod
 			//should be disabled if you're not a moderator
-			if ( 403 == status )
+			if ( HTTP_FORBIDDEN == getStatus() )
 			{
 				gIMMgr->showSessionEventError(
 					"mute",
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 81bc70906ddbf65112984686d1a4f06b31343771..d61a87c031c2018f687ba45d14f2f3090a2b002f 100755
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -36,7 +36,7 @@
 
 #include "lldir.h"
 #include "llhttpclient.h"
-#include "llhttpstatuscodes.h"
+#include "llhttpconstants.h"
 #include "llimage.h"
 #include "llimagej2c.h"
 #include "llimageworker.h"
@@ -2350,9 +2350,10 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
 	mHttpRequest = new LLCore::HttpRequest;
 	mHttpOptions = new LLCore::HttpOptions;
 	mHttpHeaders = new LLCore::HttpHeaders;
-	mHttpHeaders->mHeaders.push_back("Accept: image/x-j2c");
+	// *TODO: Should this be 'image/j2c' instead of 'image/x-j2c' ?
+	mHttpHeaders->mHeaders.push_back(HTTP_HEADER_ACCEPT + ": " + HTTP_CONTENT_IMAGE_X_J2C);
 	mHttpMetricsHeaders = new LLCore::HttpHeaders;
-	mHttpMetricsHeaders->mHeaders.push_back("Content-Type: application/llsd+xml");
+	mHttpMetricsHeaders->mHeaders.push_back(HTTP_HEADER_CONTENT_TYPE + ": " + HTTP_CONTENT_LLSD_XML);
 	mHttpPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicyDefault();
 }
 
@@ -3950,7 +3951,8 @@ void LLTextureFetchDebugger::init()
 	if (! mHttpHeaders)
 	{
 		mHttpHeaders = new LLCore::HttpHeaders;
-		mHttpHeaders->mHeaders.push_back("Accept: image/x-j2c");
+		// *TODO: Should this be 'image/j2c' instead of 'image/x-j2c' ?
+		mHttpHeaders->mHeaders.push_back(HTTP_HEADER_ACCEPT + ": " + HTTP_CONTENT_IMAGE_X_J2C);
 	}
 }
 
diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp
index f3d8de1904be0f2f1ccabdd0d806805806db13fa..b9840fa3e45457fc38141662cb2c8f1180c95429 100755
--- a/indra/newview/lltranslate.cpp
+++ b/indra/newview/lltranslate.cpp
@@ -84,7 +84,7 @@ bool LLGoogleTranslationHandler::parseResponse(
 		return false;
 	}
 
-	if (status != STATUS_OK)
+	if (status != HTTP_OK)
 	{
 		// Request failed. Extract error message from the response.
 		parseErrorResponse(root, status, err_msg);
@@ -186,7 +186,7 @@ bool LLBingTranslationHandler::parseResponse(
 	std::string& detected_lang,
 	std::string& err_msg) const
 {
-	if (status != STATUS_OK)
+	if (status != HTTP_OK)
 	{
 		static const std::string MSG_BEGIN_MARKER = "Message: ";
 		size_t begin = body.find(MSG_BEGIN_MARKER);
@@ -251,8 +251,6 @@ LLTranslate::TranslationReceiver::TranslationReceiver(const std::string& from_la
 
 // virtual
 void LLTranslate::TranslationReceiver::completedRaw(
-	U32 http_status,
-	const std::string& reason,
 	const LLChannelDescriptors& channels,
 	const LLIOPipe::buffer_ptr_t& buffer)
 {
@@ -262,8 +260,8 @@ void LLTranslate::TranslationReceiver::completedRaw(
 
 	const std::string body = strstrm.str();
 	std::string translation, detected_lang, err_msg;
-	int status = http_status;
-	LL_DEBUGS("Translate") << "HTTP status: " << status << " " << reason << LL_ENDL;
+	int status = getStatus();
+	LL_DEBUGS("Translate") << "HTTP status: " << status << " " << getReason() << LL_ENDL;
 	LL_DEBUGS("Translate") << "Response body: " << body << LL_ENDL;
 	if (mHandler.parseResponse(status, body, translation, detected_lang, err_msg))
 	{
@@ -301,12 +299,10 @@ LLTranslate::EService LLTranslate::KeyVerificationReceiver::getService() const
 
 // virtual
 void LLTranslate::KeyVerificationReceiver::completedRaw(
-	U32 http_status,
-	const std::string& reason,
 	const LLChannelDescriptors& channels,
 	const LLIOPipe::buffer_ptr_t& buffer)
 {
-	bool ok = (http_status == 200);
+	bool ok = (getStatus() == HTTP_OK);
 	setVerificationStatus(ok);
 }
 
@@ -398,8 +394,8 @@ void LLTranslate::sendRequest(const std::string& url, LLHTTPClient::ResponderPtr
 			LLVersionInfo::getPatch(),
 			LLVersionInfo::getBuild());
 
-		sHeader.insert("Accept", "text/plain");
-		sHeader.insert("User-Agent", user_agent);
+		sHeader.insert(HTTP_HEADER_ACCEPT, HTTP_CONTENT_TEXT_PLAIN);
+		sHeader.insert(HTTP_HEADER_USER_AGENT, user_agent);
 	}
 
 	LLHTTPClient::get(url, responder, sHeader, REQUEST_TIMEOUT);
diff --git a/indra/newview/lltranslate.h b/indra/newview/lltranslate.h
index db5ad9479c13c5bb2f9b42a45ebb8e72b696babb..972274714a073607d8b498bbdaba01475ac51ac6 100755
--- a/indra/newview/lltranslate.h
+++ b/indra/newview/lltranslate.h
@@ -95,9 +95,6 @@ class LLTranslationAPIHandler
 	virtual bool isConfigured() const = 0;
 
 	virtual ~LLTranslationAPIHandler() {}
-
-protected:
-	static const int STATUS_OK = 200;
 };
 
 /// Google Translate v2 API handler.
@@ -201,8 +198,6 @@ public :
 		 * @see mHandler
 		 */
 		/*virtual*/ void completedRaw(
-			U32 http_status,
-			const std::string& reason,
 			const LLChannelDescriptors& channels,
 			const LLIOPipe::buffer_ptr_t& buffer);
 
@@ -250,8 +245,6 @@ public :
 		 * @see setVerificationStatus()
 		 */
 		/*virtual*/ void completedRaw(
-			U32 http_status,
-			const std::string& reason,
 			const LLChannelDescriptors& channels,
 			const LLIOPipe::buffer_ptr_t& buffer);
 
diff --git a/indra/newview/lluploadfloaterobservers.cpp b/indra/newview/lluploadfloaterobservers.cpp
index 1d777b3f7f380be2e6fc0e560a52d580dc900851..88c48ba0a3279a6a1eb6a976029abd1684e45dae 100644
--- a/indra/newview/lluploadfloaterobservers.cpp
+++ b/indra/newview/lluploadfloaterobservers.cpp
@@ -1,6 +1,6 @@
 /**
  * @file lluploadfloaterobservers.cpp
- * @brief LLUploadModelPremissionsResponder definition
+ * @brief LLUploadModelPermissionsResponder definition
  *
  * $LicenseInfo:firstyear=2011&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -28,26 +28,31 @@
 
 #include "lluploadfloaterobservers.h"
 
-LLUploadModelPremissionsResponder::LLUploadModelPremissionsResponder(const LLHandle<LLUploadPermissionsObserver>& observer)
+LLUploadModelPermissionsResponder::LLUploadModelPermissionsResponder(const LLHandle<LLUploadPermissionsObserver>& observer)
 :mObserverHandle(observer)
 {
 }
 
-void LLUploadModelPremissionsResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+void LLUploadModelPermissionsResponder::httpFailure()
 {
-	llwarns << "LLUploadModelPremissionsResponder error [status:"
-			<< status << "]: " << content << llendl;
+	llwarns << dumpResponse() << llendl;
 
 	LLUploadPermissionsObserver* observer = mObserverHandle.get();
 
 	if (observer)
 	{
-		observer->setPermissonsErrorStatus(status, reason);
+		observer->setPermissonsErrorStatus(getStatus(), getReason());
 	}
 }
 
-void LLUploadModelPremissionsResponder::result(const LLSD& content)
+void LLUploadModelPermissionsResponder::httpSuccess()
 {
+	const LLSD& content = getContent();
+	if (!content.isMap())
+	{
+		failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+		return;
+	}
 	LLUploadPermissionsObserver* observer = mObserverHandle.get();
 
 	if (observer)
@@ -55,3 +60,4 @@ void LLUploadModelPremissionsResponder::result(const LLSD& content)
 		observer->onPermissionsReceived(content);
 	}
 }
+
diff --git a/indra/newview/lluploadfloaterobservers.h b/indra/newview/lluploadfloaterobservers.h
index b43ddb44d95456e57c9e952a51153c4409675d39..4ff4a827a5ee5f9a409e5f4052909a9d064add6d 100644
--- a/indra/newview/lluploadfloaterobservers.h
+++ b/indra/newview/lluploadfloaterobservers.h
@@ -1,6 +1,6 @@
 /**
  * @file lluploadfloaterobservers.h
- * @brief LLUploadModelPremissionsResponder declaration
+ * @brief LLUploadModelPermissionsResponder declaration
  *
  * $LicenseInfo:firstyear=2011&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -39,7 +39,7 @@ class LLUploadPermissionsObserver
 	virtual ~LLUploadPermissionsObserver() {}
 
 	virtual void onPermissionsReceived(const LLSD& result) = 0;
-	virtual void setPermissonsErrorStatus(U32 status, const std::string& reason) = 0;
+	virtual void setPermissonsErrorStatus(S32 status, const std::string& reason) = 0;
 
 	LLHandle<LLUploadPermissionsObserver> getPermObserverHandle() const {return mUploadPermObserverHandle;}
 
@@ -54,7 +54,7 @@ class LLWholeModelFeeObserver
 	virtual ~LLWholeModelFeeObserver() {}
 
 	virtual void onModelPhysicsFeeReceived(const LLSD& result, std::string upload_url) = 0;
-	virtual void setModelPhysicsFeeErrorStatus(U32 status, const std::string& reason) = 0;
+	virtual void setModelPhysicsFeeErrorStatus(S32 status, const std::string& reason) = 0;
 
 	LLHandle<LLWholeModelFeeObserver> getWholeModelFeeObserverHandle() const { return mWholeModelFeeObserverHandle; }
 
@@ -80,17 +80,16 @@ class LLWholeModelUploadObserver
 };
 
 
-class LLUploadModelPremissionsResponder : public LLHTTPClient::Responder
+class LLUploadModelPermissionsResponder : public LLHTTPClient::Responder
 {
+	LOG_CLASS(LLUploadModelPermissionsResponder);
 public:
-
-	LLUploadModelPremissionsResponder(const LLHandle<LLUploadPermissionsObserver>& observer);
-
-	void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
-
-	void result(const LLSD& content);
+	LLUploadModelPermissionsResponder(const LLHandle<LLUploadPermissionsObserver>& observer);
 
 private:
+	/* virtual */ void httpSuccess();
+	/* virtual */ void httpFailure();
+
 	LLHandle<LLUploadPermissionsObserver> mObserverHandle;
 };
 
diff --git a/indra/newview/llviewerdisplayname.cpp b/indra/newview/llviewerdisplayname.cpp
index 1ac6a90894a36e36f2c7d5c83281fb46edc0a8d0..07fceefde063781b8dc6ebe76723589a24ba0a1b 100644
--- a/indra/newview/llviewerdisplayname.cpp
+++ b/indra/newview/llviewerdisplayname.cpp
@@ -57,12 +57,12 @@ namespace LLViewerDisplayName
 
 class LLSetDisplayNameResponder : public LLHTTPClient::Responder
 {
-public:
+	LOG_CLASS(LLSetDisplayNameResponder);
+private:
 	// only care about errors
-	/*virtual*/ void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+	/*virtual*/ void httpFailure()
 	{
-		llwarns << "LLSetDisplayNameResponder error [status:"
-				<< status << "]: " << content << llendl;
+		llwarns << dumpResponse() << llendl;
 		LLViewerDisplayName::sSetDisplayNameSignal(false, "", LLSD());
 		LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots();
 	}
@@ -85,7 +85,7 @@ void LLViewerDisplayName::set(const std::string& display_name, const set_name_sl
 	// People API can return localized error messages.  Indicate our
 	// language preference via header.
 	LLSD headers;
-	headers["Accept-Language"] = LLUI::getLanguage();
+	headers[HTTP_HEADER_ACCEPT_LANGUAGE] = LLUI::getLanguage();
 
 	// People API requires both the old and new value to change a variable.
 	// Our display name will be in cache before the viewer's UI is available
@@ -127,7 +127,7 @@ class LLSetDisplayNameReply : public LLHTTPNode
 		LLSD body = input["body"];
 
 		S32 status = body["status"].asInteger();
-		bool success = (status == 200);
+		bool success = (status == HTTP_OK);
 		std::string reason = body["reason"].asString();
 		LLSD content = body["content"];
 
@@ -136,7 +136,7 @@ class LLSetDisplayNameReply : public LLHTTPNode
 		// If viewer's concept of display name is out-of-date, the set request
 		// will fail with 409 Conflict.  If that happens, fetch up-to-date
 		// name information.
-		if (status == 409)
+		if (status == HTTP_CONFLICT)
 		{
 			LLUUID agent_id = gAgent.getID();
 			// Flush stale data
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 2df028de69c098fcf3f58c64c4c0f316b62fa332..8c29a03176d1f947fec7d5b576e109bd8a868920 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -158,7 +158,7 @@ LLViewerMediaObserver::~LLViewerMediaObserver()
 // on the Panel Land Media and to discover the MIME type
 class LLMimeDiscoveryResponder : public LLHTTPClient::Responder
 {
-LOG_CLASS(LLMimeDiscoveryResponder);
+	LOG_CLASS(LLMimeDiscoveryResponder);
 public:
 	LLMimeDiscoveryResponder( viewer_media_t media_impl)
 		: mMediaImpl(media_impl),
@@ -177,13 +177,20 @@ LOG_CLASS(LLMimeDiscoveryResponder);
 		disconnectOwner();
 	}
 
-	virtual void completedHeader(U32 status, const std::string& reason, const LLSD& content)
+private:
+	/* virtual */ void httpCompleted()
 	{
-		std::string media_type = content["content-type"].asString();
+		if (!isGoodStatus())
+		{
+			llwarns << dumpResponse()
+					<< " [headers:" << getResponseHeaders() << "]" << llendl;
+		}
+		const bool check_lower = true;
+		const std::string& media_type = getResponseHeader(HTTP_HEADER_CONTENT_TYPE, check_lower);
 		std::string::size_type idx1 = media_type.find_first_of(";");
 		std::string mime_type = media_type.substr(0, idx1);
 
-		lldebugs << "status is " << status << ", media type \"" << media_type << "\"" << llendl;
+		lldebugs << "status is " << getStatus() << ", media type \"" << media_type << "\"" << llendl;
 		
 		// 2xx status codes indicate success.
 		// Most 4xx status codes are successful enough for our purposes.
@@ -200,32 +207,27 @@ LOG_CLASS(LLMimeDiscoveryResponder);
 //			)
 		// We now no longer check the error code returned from the probe.
 		// If we have a mime type, use it.  If not, default to the web plugin and let it handle error reporting.
-		if(1)
+		//if(1)
 		{
 			// The probe was successful.
 			if(mime_type.empty())
 			{
 				// Some sites don't return any content-type header at all.
 				// Treat an empty mime type as text/html.
-				mime_type = "text/html";
+				mime_type = HTTP_CONTENT_TEXT_HTML;
 			}
-			
-			completeAny(status, mime_type);
 		}
-		else
-		{
-			llwarns << "responder failed with status " << status << ", reason " << reason << llendl;
-		
-			if(mMediaImpl)
-			{
-				mMediaImpl->mMediaSourceFailed = true;
-			}
-		}
-
-	}
+		//else
+		//{
+		//	llwarns << "responder failed with status " << dumpResponse() << llendl;
+		//
+		//	if(mMediaImpl)
+		//	{
+		//		mMediaImpl->mMediaSourceFailed = true;
+		//	}
+		//	return;
+		//}
 
-	void completeAny(U32 status, const std::string& mime_type)
-	{
 		// the call to initializeMedia may disconnect the responder, which will clear mMediaImpl.
 		// Make a local copy so we can call loadURI() afterwards.
 		LLViewerMediaImpl *impl = mMediaImpl;
@@ -241,6 +243,7 @@ LOG_CLASS(LLMimeDiscoveryResponder);
 		}
 	}
 	
+public:
 	void cancelRequest()
 	{
 		disconnectOwner();
@@ -269,7 +272,7 @@ LOG_CLASS(LLMimeDiscoveryResponder);
 
 class LLViewerMediaOpenIDResponder : public LLHTTPClient::Responder
 {
-LOG_CLASS(LLViewerMediaOpenIDResponder);
+	LOG_CLASS(LLViewerMediaOpenIDResponder);
 public:
 	LLViewerMediaOpenIDResponder( )
 	{
@@ -279,23 +282,18 @@ LOG_CLASS(LLViewerMediaOpenIDResponder);
 	{
 	}
 
-	/* virtual */ void completedHeader(U32 status, const std::string& reason, const LLSD& content)
-	{
-		LL_DEBUGS("MediaAuth") << "status = " << status << ", reason = " << reason << LL_ENDL;
-		LL_DEBUGS("MediaAuth") << content << LL_ENDL;
-		std::string cookie = content["set-cookie"].asString();
-		
-		LLViewerMedia::openIDCookieResponse(cookie);
-	}
-
 	/* virtual */ void completedRaw(
-		U32 status,
-		const std::string& reason,
 		const LLChannelDescriptors& channels,
 		const LLIOPipe::buffer_ptr_t& buffer)
 	{
-		// This is just here to disable the default behavior (attempting to parse the response as llsd).
-		// We don't care about the content of the response, only the set-cookie header.
+		// We don't care about the content of the response, only the Set-Cookie header.
+		LL_DEBUGS("MediaAuth") << dumpResponse() 
+				<< " [headers:" << getResponseHeaders() << "]" << LL_ENDL;
+		const bool check_lower = true;
+		const std::string& cookie = getResponseHeader(HTTP_HEADER_SET_COOKIE, check_lower);
+		
+		// *TODO: What about bad status codes?  Does this destroy previous cookies?
+		LLViewerMedia::openIDCookieResponse(cookie);
 	}
 
 };
@@ -313,17 +311,25 @@ LOG_CLASS(LLViewerMediaWebProfileResponder);
 	{
 	}
 
-	/* virtual */ void completedHeader(U32 status, const std::string& reason, const LLSD& content)
+	 void completedRaw(
+		const LLChannelDescriptors& channels,
+		const LLIOPipe::buffer_ptr_t& buffer)
 	{
-		LL_WARNS("MediaAuth") << "status = " << status << ", reason = " << reason << LL_ENDL;
+		// We don't care about the content of the response, only the set-cookie header.
+		LL_WARNS("MediaAuth") << dumpResponse() 
+				<< " [headers:" << getResponseHeaders() << "]" << LL_ENDL;
 
-		LLSD stripped_content = content;
+		LLSD stripped_content = getResponseHeaders();
+		// *TODO: Check that this works.
+		stripped_content.erase(HTTP_HEADER_SET_COOKIE);
 		stripped_content.erase("set-cookie");
 		LL_WARNS("MediaAuth") << stripped_content << LL_ENDL;
 
-		std::string cookie = content["set-cookie"].asString();
+		const bool check_lower = true;
+		const std::string& cookie = getResponseHeader(HTTP_HEADER_SET_COOKIE, check_lower);
 		LL_DEBUGS("MediaAuth") << "cookie = " << cookie << LL_ENDL;
 
+		// *TODO: What about bad status codes?  Does this destroy previous cookies?
 		LLViewerMedia::getCookieStore()->setCookiesFromHost(cookie, mHost);
 
 		// Set cookie for snapshot publishing.
@@ -331,16 +337,6 @@ LOG_CLASS(LLViewerMediaWebProfileResponder);
 		LLWebProfile::setAuthCookie(auth_cookie);
 	}
 
-	 void completedRaw(
-		U32 status,
-		const std::string& reason,
-		const LLChannelDescriptors& channels,
-		const LLIOPipe::buffer_ptr_t& buffer)
-	{
-		// This is just here to disable the default behavior (attempting to parse the response as llsd).
-		// We don't care about the content of the response, only the set-cookie header.
-	}
-
 	std::string mHost;
 };
 
@@ -1387,10 +1383,12 @@ void LLViewerMedia::removeCookie(const std::string &name, const std::string &dom
 LLSD LLViewerMedia::getHeaders()
 {
 	LLSD headers = LLSD::emptyMap();
-	headers["Accept"] = "*/*";
-	headers["Content-Type"] = "application/xml";
-	headers["Cookie"] = sOpenIDCookie;
-	headers["User-Agent"] = getCurrentUserAgent();
+	headers[HTTP_HEADER_ACCEPT] = "*/*";
+	// *TODO: Should this be 'application/llsd+xml' ?
+	// *TODO: Should this even be set at all?   This header is only not overridden in 'GET' methods.
+	headers[HTTP_HEADER_CONTENT_TYPE] = HTTP_CONTENT_XML;
+	headers[HTTP_HEADER_COOKIE] = sOpenIDCookie;
+	headers[HTTP_HEADER_USER_AGENT] = getCurrentUserAgent();
 
 	return headers;
 }
@@ -1431,9 +1429,9 @@ void LLViewerMedia::setOpenIDCookie()
 
 		// Do a web profile get so we can store the cookie 
 		LLSD headers = LLSD::emptyMap();
-		headers["Accept"] = "*/*";
-		headers["Cookie"] = sOpenIDCookie;
-		headers["User-Agent"] = getCurrentUserAgent();
+		headers[HTTP_HEADER_ACCEPT] = "*/*";
+		headers[HTTP_HEADER_COOKIE] = sOpenIDCookie;
+		headers[HTTP_HEADER_USER_AGENT] = getCurrentUserAgent();
 
 		std::string profile_url = getProfileURL("");
 		LLURL raw_profile_url( profile_url.c_str() );
@@ -1463,9 +1461,9 @@ void LLViewerMedia::openIDSetup(const std::string &openid_url, const std::string
 
 	LLSD headers = LLSD::emptyMap();
 	// Keep LLHTTPClient from adding an "Accept: application/llsd+xml" header
-	headers["Accept"] = "*/*";
+	headers[HTTP_HEADER_ACCEPT] = "*/*";
 	// and use the expected content-type for a post, instead of the LLHTTPClient::postRaw() default of "application/octet-stream"
-	headers["Content-Type"] = "application/x-www-form-urlencoded";
+	headers[HTTP_HEADER_CONTENT_TYPE] = "application/x-www-form-urlencoded";
 
 	// postRaw() takes ownership of the buffer and releases it later, so we need to allocate a new buffer here.
 	size_t size = openid_token.size();
@@ -1537,7 +1535,7 @@ void LLViewerMedia::createSpareBrowserMediaSource()
 		// The null owner will keep the browser plugin from fully initializing 
 		// (specifically, it keeps LLPluginClassMedia from negotiating a size change, 
 		// which keeps MediaPluginWebkit::initBrowserWindow from doing anything until we have some necessary data, like the background color)
-		sSpareBrowserMediaSource = LLViewerMediaImpl::newSourceFromMediaType("text/html", NULL, 0, 0);
+		sSpareBrowserMediaSource = LLViewerMediaImpl::newSourceFromMediaType(HTTP_CONTENT_TEXT_HTML, NULL, 0, 0);
 	}
 }
 
@@ -2633,16 +2631,16 @@ void LLViewerMediaImpl::navigateInternal()
 			//    Accept: application/llsd+xml
 			// which is really not what we want.
 			LLSD headers = LLSD::emptyMap();
-			headers["Accept"] = "*/*";
+			headers[HTTP_HEADER_ACCEPT] = "*/*";
 			// Allow cookies in the response, to prevent a redirect loop when accessing join.secondlife.com
-			headers["Cookie"] = "";
+			headers[HTTP_HEADER_COOKIE] = "";
 			LLHTTPClient::getHeaderOnly( mMediaURL, new LLMimeDiscoveryResponder(this), headers, 10.0f);
 		}
 		else if("data" == scheme || "file" == scheme || "about" == scheme)
 		{
 			// FIXME: figure out how to really discover the type for these schemes
 			// We use "data" internally for a text/html url for loading the login screen
-			if(initializeMedia("text/html"))
+			if(initializeMedia(HTTP_CONTENT_TEXT_HTML))
 			{
 				loadURI();
 			}
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 0561e731e79505aacc4592315db0e44fa616c705..576b801d5bf6a906b94626125c1444e9cc001ba2 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -671,6 +671,7 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent)
 
 class LLObjectCostResponder : public LLCurl::Responder
 {
+	LOG_CLASS(LLObjectCostResponder);
 public:
 	LLObjectCostResponder(const LLSD& object_ids)
 		: mObjectIDs(object_ids)
@@ -691,20 +692,19 @@ class LLObjectCostResponder : public LLCurl::Responder
 		}
 	}
 
-	void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
+private:
+	/* virtual */ void httpFailure()
 	{
-		llwarns
-			<< "Transport error requesting object cost "
-			<< "[status: " << statusNum << "]: "
-			<< content << llendl;
+		llwarns << dumpResponse() << llendl;
 
 		// TODO*: Error message to user
 		// For now just clear the request from the pending list
 		clear_object_list_pending_requests();
 	}
 
-	void result(const LLSD& content)
+	/* virtual */ void httpSuccess()
 	{
+		const LLSD& content = getContent();
 		if ( !content.isMap() || content.has("error") )
 		{
 			// Improper response or the request had an error,
@@ -760,6 +760,7 @@ class LLObjectCostResponder : public LLCurl::Responder
 
 class LLPhysicsFlagsResponder : public LLCurl::Responder
 {
+	LOG_CLASS(LLPhysicsFlagsResponder);
 public:
 	LLPhysicsFlagsResponder(const LLSD& object_ids)
 		: mObjectIDs(object_ids)
@@ -780,20 +781,19 @@ class LLPhysicsFlagsResponder : public LLCurl::Responder
 		}
 	}
 
-	void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
+private:
+	/* virtual */ void httpFailure()
 	{
-		llwarns
-			<< "Transport error requesting object physics flags "
-			<< "[status: " << statusNum << "]: "
-			<< content << llendl;
+		llwarns << dumpResponse() << llendl;
 
 		// TODO*: Error message to user
 		// For now just clear the request from the pending list
 		clear_object_list_pending_requests();
 	}
 
-	void result(const LLSD& content)
+	/* virtual void */ void httpSuccess()
 	{
+		const LLSD& content = getContent();
 		if ( !content.isMap() || content.has("error") )
 		{
 			// Improper response or the request had an error,
diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp
index 386b2fd4001a4807f086322a7386c5e604430247..d7e14ac6f532fa60fb51af2a1ae52dddb59e830b 100644
--- a/indra/newview/llviewerparcelmedia.cpp
+++ b/indra/newview/llviewerparcelmedia.cpp
@@ -99,7 +99,7 @@ void LLViewerParcelMedia::update(LLParcel* parcel)
 			std::string mediaCurrentUrl = std::string( parcel->getMediaCurrentURL());
 
 			// if we have a current (link sharing) url, use it instead
-			if (mediaCurrentUrl != "" && parcel->getMediaType() == "text/html")
+			if (mediaCurrentUrl != "" && parcel->getMediaType() == HTTP_CONTENT_TEXT_HTML)
 			{
 				mediaUrl = mediaCurrentUrl;
 			}
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index b8b53aa6e45f9cc83ea75b4d187313a0f170cb3a..2286bb09e1dee36489e9df49e43c5fb31841dcbc 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -204,24 +204,30 @@ class BaseCapabilitiesComplete : public LLHTTPClient::Responder
 {
 	LOG_CLASS(BaseCapabilitiesComplete);
 public:
-    BaseCapabilitiesComplete(U64 region_handle, S32 id)
+	BaseCapabilitiesComplete(U64 region_handle, S32 id)
 		: mRegionHandle(region_handle), mID(id)
-    { }
+	{ }
 	virtual ~BaseCapabilitiesComplete()
 	{ }
 
-    void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
-    {
-		LL_WARNS2("AppInit", "Capabilities") << "[status:" << statusNum << ":] " << content << LL_ENDL;
+	static BaseCapabilitiesComplete* build( U64 region_handle, S32 id )
+	{
+		return new BaseCapabilitiesComplete(region_handle, id);
+	}
+
+private:
+	/* virtual */void httpFailure()
+	{
+		LL_WARNS2("AppInit", "Capabilities") << dumpResponse() << LL_ENDL;
 		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
 		if (regionp)
 		{
 			regionp->failedSeedCapability();
 		}
-    }
+	}
 
-   void result(const LLSD& content)
-    {
+	/* virtual */ void httpSuccess()
+	{
 		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
 		if(!regionp) //region was removed
 		{
@@ -234,11 +240,17 @@ class BaseCapabilitiesComplete : public LLHTTPClient::Responder
 			return ;
 		}
 
+		const LLSD& content = getContent();
+		if (!content.isMap())
+		{
+			failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+			return;
+		}
 		LLSD::map_const_iterator iter;
 		for(iter = content.beginMap(); iter != content.endMap(); ++iter)
 		{
 			regionp->setCapability(iter->first, iter->second);
-			
+
 			LL_DEBUGS2("AppInit", "Capabilities") << "got capability for " 
 				<< iter->first << LL_ENDL;
 
@@ -257,11 +269,6 @@ class BaseCapabilitiesComplete : public LLHTTPClient::Responder
 		}
 	}
 
-    static BaseCapabilitiesComplete* build( U64 region_handle, S32 id )
-    {
-		return new BaseCapabilitiesComplete(region_handle, id);
-    }
-
 private:
 	U64 mRegionHandle;
 	S32 mID;
@@ -278,19 +285,32 @@ class BaseCapabilitiesCompleteTracker :  public LLHTTPClient::Responder
 	virtual ~BaseCapabilitiesCompleteTracker()
 	{ }
 
-	void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
+	static BaseCapabilitiesCompleteTracker* build( U64 region_handle )
+	{
+		return new BaseCapabilitiesCompleteTracker( region_handle );
+	}
+
+private:
+	/* virtual */ void httpFailure()
 	{
-		llwarns << "BaseCapabilitiesCompleteTracker error [status:"
-				<< statusNum << "]: " << content << llendl;
+		llwarns << dumpResponse() << llendl;
 	}
 
-	void result(const LLSD& content)
+	/* virtual */ void httpSuccess()
 	{
 		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
 		if( !regionp ) 
 		{
+			LL_WARNS2("AppInit", "Capabilities") << "Received results for region that no longer exists!" << LL_ENDL;
 			return ;
-		}		
+		}
+
+		const LLSD& content = getContent();
+		if (!content.isMap())
+		{
+			failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+			return;
+		}
 		LLSD::map_const_iterator iter;
 		for(iter = content.beginMap(); iter != content.endMap(); ++iter)
 		{
@@ -300,7 +320,8 @@ class BaseCapabilitiesCompleteTracker :  public LLHTTPClient::Responder
 		
 		if ( regionp->getRegionImpl()->mCapabilities.size() != regionp->getRegionImpl()->mSecondCapabilitiesTracker.size() )
 		{
-			llinfos<<"BaseCapabilitiesCompleteTracker "<<"Sim sent duplicate seed caps that differs in size - most likely content."<<llendl;			
+			LL_WARNS2("AppInit", "Capabilities") 
+				<< "Sim sent duplicate seed caps that differs in size - most likely content." << LL_ENDL;
 			//todo#add cap debug versus original check?
 			/*CapabilityMap::const_iterator iter = regionp->getRegionImpl()->mCapabilities.begin();
 			while (iter!=regionp->getRegionImpl()->mCapabilities.end() )
@@ -311,16 +332,11 @@ class BaseCapabilitiesCompleteTracker :  public LLHTTPClient::Responder
 			*/
 			regionp->getRegionImplNC()->mSecondCapabilitiesTracker.clear();
 		}
-
 	}
 
-	static BaseCapabilitiesCompleteTracker* build( U64 region_handle )
-	{
-		return new BaseCapabilitiesCompleteTracker( region_handle );
-	}
 
 private:
-	U64 mRegionHandle;	
+	U64 mRegionHandle;
 };
 
 
@@ -1728,31 +1744,37 @@ class SimulatorFeaturesReceived : public LLHTTPClient::Responder
 {
 	LOG_CLASS(SimulatorFeaturesReceived);
 public:
-    SimulatorFeaturesReceived(const std::string& retry_url, U64 region_handle, 
+	SimulatorFeaturesReceived(const std::string& retry_url, U64 region_handle, 
 			S32 attempt = 0, S32 max_attempts = MAX_CAP_REQUEST_ATTEMPTS)
-	: mRetryURL(retry_url), mRegionHandle(region_handle), mAttempt(attempt), mMaxAttempts(max_attempts)
-    { }
-	
-	
-    void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
-    {
-		LL_WARNS2("AppInit", "SimulatorFeatures") << "[status:" << statusNum << "]: " << content << LL_ENDL;
+		: mRetryURL(retry_url), mRegionHandle(region_handle), mAttempt(attempt), mMaxAttempts(max_attempts)
+	{ }
+
+private:
+	/* virtual */ void httpFailure()
+	{
+		LL_WARNS2("AppInit", "SimulatorFeatures") << dumpResponse() << LL_ENDL;
 		retry();
-    }
+	}
 
-    void result(const LLSD& content)
-    {
+	/* virtual */ void httpSuccess()
+	{
 		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
 		if(!regionp) //region is removed or responder is not created.
 		{
-			LL_WARNS2("AppInit", "SimulatorFeatures") << "Received results for region that no longer exists!" << LL_ENDL;
+			LL_WARNS2("AppInit", "SimulatorFeatures") 
+				<< "Received results for region that no longer exists!" << LL_ENDL;
 			return ;
 		}
-		
+
+		const LLSD& content = getContent();
+		if (!content.isMap())
+		{
+			failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+			return;
+		}
 		regionp->setSimulatorFeatures(content);
 	}
 
-private:
 	void retry()
 	{
 		if (mAttempt < mMaxAttempts)
@@ -1762,7 +1784,7 @@ class SimulatorFeaturesReceived : public LLHTTPClient::Responder
 			LLHTTPClient::get(mRetryURL, new SimulatorFeaturesReceived(*this), LLSD(), CAP_REQUEST_TIMEOUT);
 		}
 	}
-	
+
 	std::string mRetryURL;
 	U64 mRegionHandle;
 	S32 mAttempt;
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 4ed01f36ab754e8b5cd0b5224923eefad8381617..a9256ed5ead187ef1027e258319c593a79dd5982 100755
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -527,18 +527,19 @@ void update_statistics()
 
 class ViewerStatsResponder : public LLHTTPClient::Responder
 {
+	LOG_CLASS(ViewerStatsResponder);
 public:
-    ViewerStatsResponder() { }
+	ViewerStatsResponder() { }
 
-    void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
-    {
-		llwarns << "ViewerStatsResponder error [status:" << statusNum << "]: "
-				<< content << llendl;
-    }
+private:
+	/* virtual */ void httpFailure()
+	{
+		llwarns << dumpResponse() << llendl;
+	}
 
-    void result(const LLSD& content)
-    {
-		llinfos << "ViewerStatsResponder::result" << llendl;
+	/* virtual */ void httpSuccess()
+	{
+		llinfos << "OK" << llendl;
 	}
 };
 
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index a98e9ce511b0d9bd1e803cd2f2fb2063391be256..7e95263f4be683a95b2d3f4914b1fa0be8647e76 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1914,7 +1914,7 @@ void LLViewerWindow::initWorldUI()
 		destinations->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL"));
 		std::string url = gSavedSettings.getString("DestinationGuideURL");
 		url = LLWeb::expandURLSubstitutions(url, LLSD());
-		destinations->navigateTo(url, "text/html");
+		destinations->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
 	}
 	LLMediaCtrl* avatar_picker = LLFloaterReg::getInstance("avatar")->findChild<LLMediaCtrl>("avatar_picker_contents");
 	if (avatar_picker)
@@ -1922,7 +1922,7 @@ void LLViewerWindow::initWorldUI()
 		avatar_picker->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL"));
 		std::string url = gSavedSettings.getString("AvatarPickerURL");
 		url = LLWeb::expandURLSubstitutions(url, LLSD());
-		avatar_picker->navigateTo(url, "text/html");
+		avatar_picker->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
 	}
 }
 
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 9be1de4f0e1e0e6b4481dbe4d9a19557e01be331..81454f5da4260b89aa4b77882f6e2776a5488bb9 100755
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -2241,6 +2241,7 @@ LLSD LLVOAvatarSelf::metricsData()
 
 class ViewerAppearanceChangeMetricsResponder: public LLCurl::Responder
 {
+	LOG_CLASS(ViewerAppearanceChangeMetricsResponder);
 public:
 	ViewerAppearanceChangeMetricsResponder( S32 expected_sequence,
 											volatile const S32 & live_sequence,
@@ -2251,32 +2252,25 @@ class ViewerAppearanceChangeMetricsResponder: public LLCurl::Responder
 	{
 	}
 
-	virtual void completed(U32 status,
-						   const std::string& reason,
-						   const LLSD& content)
+private:
+	/* virtual */ void httpSuccess()
 	{
-		gPendingMetricsUploads--; // if we add retry, this should be moved to the isGoodStatus case.
-		if (isGoodStatus(status))
-		{
-			LL_DEBUGS("Avatar") << "OK" << LL_ENDL;
-			result(content);
-		}
-		else
-		{
-			LL_WARNS("Avatar") << "Failed " << status << " reason " << reason << LL_ENDL;
-			errorWithContent(status,reason,content);
-		}
-	}
+		LL_DEBUGS("Avatar") << "OK" << LL_ENDL;
 
-	// virtual
-	void result(const LLSD & content)
-	{
+		gPendingMetricsUploads--;
 		if (mLiveSequence == mExpectedSequence)
 		{
 			mReportingStarted = true;
 		}
 	}
 
+	/* virtual */ void httpFailure()
+	{
+		// if we add retry, this should be removed from the httpFailure case
+		LL_WARNS("Avatar") << dumpResponse() << LL_ENDL;
+		gPendingMetricsUploads--;
+	}
+
 private:
 	S32 mExpectedSequence;
 	volatile const S32 & mLiveSequence;
@@ -2425,6 +2419,7 @@ void LLVOAvatarSelf::sendViewerAppearanceChangeMetrics()
 
 class CheckAgentAppearanceServiceResponder: public LLHTTPClient::Responder
 {
+	LOG_CLASS(CheckAgentAppearanceServiceResponder);
 public:
 	CheckAgentAppearanceServiceResponder()
 	{
@@ -2434,22 +2429,24 @@ class CheckAgentAppearanceServiceResponder: public LLHTTPClient::Responder
 	{
 	}
 
-	/* virtual */ void result(const LLSD& content)
+private:
+	/* virtual */ void httpSuccess()
 	{
-		LL_DEBUGS("Avatar") << "status OK" << llendl;
+		LL_DEBUGS("Avatar") << "OK" << llendl;
 	}
 
 	// Error
-	/*virtual*/ void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+	/*virtual*/ void httpFailure()
 	{
 		if (isAgentAvatarValid())
 		{
-			LL_DEBUGS("Avatar") << "failed, will rebake [status:"
-					<< status << "]: " << content << llendl;
+			LL_DEBUGS("Avatar") << "failed, will rebake "
+					<< dumpResponse() << LL_ENDL;
 			forceAppearanceUpdate();
 		}
-	}	
+	}
 
+public:
 	static void forceAppearanceUpdate()
 	{
 		// Trying to rebake immediately after crossing region boundary
diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp
index 181735ee3092917c1eed7314f6cceb83188e57b5..be836d77525b0d5d9310b5955c427733e023512a 100644
--- a/indra/newview/llvoicechannel.cpp
+++ b/indra/newview/llvoicechannel.cpp
@@ -53,26 +53,27 @@ const U32 DEFAULT_RETRIES_COUNT = 3;
 
 class LLVoiceCallCapResponder : public LLHTTPClient::Responder
 {
+	LOG_CLASS(LLVoiceCallCapResponder);
 public:
 	LLVoiceCallCapResponder(const LLUUID& session_id) : mSessionID(session_id) {};
 
+protected:
 	// called with bad status codes
-	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
-	virtual void result(const LLSD& content);
+	virtual void httpFailure();
+	virtual void httpSuccess();
 
 private:
 	LLUUID mSessionID;
 };
 
 
-void LLVoiceCallCapResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+void LLVoiceCallCapResponder::httpFailure()
 {
-	LL_WARNS("Voice") << "LLVoiceCallCapResponder error [status:"
-		<< status << "]: " << content << LL_ENDL;
+	LL_WARNS("Voice") << dumpResponse() << LL_ENDL;
 	LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(mSessionID);
 	if ( channelp )
 	{
-		if ( 403 == status )
+		if ( HTTP_FORBIDDEN == getStatus() )
 		{
 			//403 == no ability
 			LLNotificationsUtil::add(
@@ -89,12 +90,18 @@ void LLVoiceCallCapResponder::errorWithContent(U32 status, const std::string& re
 	}
 }
 
-void LLVoiceCallCapResponder::result(const LLSD& content)
+void LLVoiceCallCapResponder::httpSuccess()
 {
 	LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(mSessionID);
 	if (channelp)
 	{
 		//*TODO: DEBUG SPAM
+		const LLSD& content = getContent();
+		if (!content.isMap())
+		{
+			failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+			return;
+		}
 		LLSD::map_const_iterator iter;
 		for(iter = content.beginMap(); iter != content.endMap(); ++iter)
 		{
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index e112c589e90d97b869c27bba7713d8178179291c..360f8f15a3cae59596ee8f29f745beee39256779 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -120,17 +120,19 @@ static int scale_speaker_volume(float volume)
 class LLVivoxVoiceAccountProvisionResponder :
 	public LLHTTPClient::Responder
 {
+	LOG_CLASS(LLVivoxVoiceAccountProvisionResponder);
 public:
 	LLVivoxVoiceAccountProvisionResponder(int retries)
 	{
 		mRetries = retries;
 	}
 
-	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+private:
+	/* virtual */ void httpFailure()
 	{
 		LL_WARNS("Voice") << "ProvisionVoiceAccountRequest returned an error, "
 			<<  ( (mRetries > 0) ? "retrying" : "too many retries (giving up)" )
-			<< status << "]: " << content << LL_ENDL;
+			<< " " << dumpResponse() << LL_ENDL;
 
 		if ( mRetries > 0 )
 		{
@@ -142,14 +144,19 @@ class LLVivoxVoiceAccountProvisionResponder :
 		}
 	}
 
-	virtual void result(const LLSD& content)
+	/* virtual */ void httpSuccess()
 	{
-
 		std::string voice_sip_uri_hostname;
 		std::string voice_account_server_uri;
 		
-		LL_DEBUGS("Voice") << "ProvisionVoiceAccountRequest response:" << ll_pretty_print_sd(content) << LL_ENDL;
+		LL_DEBUGS("Voice") << "ProvisionVoiceAccountRequest response:" << dumpResponse() << LL_ENDL;
 		
+		const LLSD& content = getContent();
+		if (!content.isMap())
+		{
+			failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+			return;
+		}
 		if(content.has("voice_sip_uri_hostname"))
 			voice_sip_uri_hostname = content["voice_sip_uri_hostname"].asString();
 		
@@ -162,7 +169,6 @@ class LLVivoxVoiceAccountProvisionResponder :
 			content["password"].asString(),
 			voice_sip_uri_hostname,
 			voice_account_server_uri);
-
 	}
 
 private:
@@ -193,33 +199,34 @@ static LLVivoxVoiceClientFriendsObserver *friendslist_listener = NULL;
 
 class LLVivoxVoiceClientCapResponder : public LLHTTPClient::Responder
 {
+	LOG_CLASS(LLVivoxVoiceClientCapResponder);
 public:
 	LLVivoxVoiceClientCapResponder(LLVivoxVoiceClient::state requesting_state) : mRequestingState(requesting_state) {};
 
+private:
 	// called with bad status codes
-	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
-	virtual void result(const LLSD& content);
+	/* virtual */ void httpFailure();
+	/* virtual */ void httpSuccess();
 
-private:
 	LLVivoxVoiceClient::state mRequestingState;  // state 
 };
 
-void LLVivoxVoiceClientCapResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+void LLVivoxVoiceClientCapResponder::httpFailure()
 {
-	LL_WARNS("Voice") << "LLVivoxVoiceClientCapResponder error [status:"
-		<< status << "]: " << content << LL_ENDL;
+	LL_WARNS("Voice") << dumpResponse() << LL_ENDL;
 	LLVivoxVoiceClient::getInstance()->sessionTerminate();
 }
 
-void LLVivoxVoiceClientCapResponder::result(const LLSD& content)
+void LLVivoxVoiceClientCapResponder::httpSuccess()
 {
 	LLSD::map_const_iterator iter;
 	
-	LL_DEBUGS("Voice") << "ParcelVoiceInfoRequest response:" << ll_pretty_print_sd(content) << LL_ENDL;
+	LL_DEBUGS("Voice") << "ParcelVoiceInfoRequest response:" << dumpResponse() << LL_ENDL;
 
 	std::string uri;
 	std::string credentials;
 	
+	const LLSD& content = getContent();
 	if ( content.has("voice_credentials") )
 	{
 		LLSD voice_credentials = content["voice_credentials"];
@@ -2982,7 +2989,7 @@ void LLVivoxVoiceClient::loginResponse(int statusCode, std::string &statusString
 	
 	// Status code of 20200 means "bad password".  We may want to special-case that at some point.
 	
-	if ( statusCode == 401 )
+	if ( statusCode == HTTP_UNAUTHORIZED )
 	{
 		// Login failure which is probably caused by the delay after a user's password being updated.
 		LL_INFOS("Voice") << "Account.Login response failure (" << statusCode << "): " << statusString << LL_ENDL;
@@ -3484,7 +3491,7 @@ void LLVivoxVoiceClient::mediaStreamUpdatedEvent(
 		switch(statusCode)
 		{
 			case 0:
-			case 200:
+			case HTTP_OK:
 				// generic success
 				// Don't change the saved error code (it may have been set elsewhere)
 			break;
@@ -3835,7 +3842,7 @@ void LLVivoxVoiceClient::messageEvent(
 	LL_DEBUGS("Voice") << "Message event, session " << sessionHandle << " from " << uriString << LL_ENDL;
 //	LL_DEBUGS("Voice") << "    header " << messageHeader << ", body: \n" << messageBody << LL_ENDL;
 	
-	if(messageHeader.find("text/html") != std::string::npos)
+	if(messageHeader.find(HTTP_CONTENT_TEXT_HTML) != std::string::npos)
 	{
 		std::string message;
 
@@ -6119,9 +6126,10 @@ void LLVivoxVoiceClient::notifyStatusObservers(LLVoiceClientStatusObserver::ESta
 		{
 			switch(mAudioSession->mErrorStatusCode)
 			{
-				case 404:	// NOT_FOUND
+				case HTTP_NOT_FOUND:	// NOT_FOUND
+				// *TODO: Should this be 503?
 				case 480:	// TEMPORARILY_UNAVAILABLE
-				case 408:	// REQUEST_TIMEOUT
+				case HTTP_REQUEST_TIME_OUT:	// REQUEST_TIMEOUT
 					// call failed because other user was not available
 					// treat this as an error case
 					status = LLVoiceClientStatusObserver::ERROR_NOT_AVAILABLE;
diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp
index 641f338f2c6be343f352a010a6d0ca3849310dbd..ee78ba20cb9e7d10928bbbff9ba06f6eac04f6fb 100644
--- a/indra/newview/llwebprofile.cpp
+++ b/indra/newview/llwebprofile.cpp
@@ -67,9 +67,8 @@ class LLWebProfileResponders::ConfigResponder : public LLHTTPClient::Responder
 	{
 	}
 
+	// *TODO: Check for 'application/json' content type, and parse json at the base class.
 	/*virtual*/ void completedRaw(
-		U32 status,
-		const std::string& reason,
 		const LLChannelDescriptors& channels,
 		const LLIOPipe::buffer_ptr_t& buffer)
 	{
@@ -78,9 +77,9 @@ class LLWebProfileResponders::ConfigResponder : public LLHTTPClient::Responder
 		strstrm << istr.rdbuf();
 		const std::string body = strstrm.str();
 
-		if (status != 200)
+		if (getStatus() != HTTP_OK)
 		{
-			llwarns << "Failed to get upload config (" << status << ")" << llendl;
+			llwarns << "Failed to get upload config " << dumpResponse() << llendl;
 			LLWebProfile::reportImageUploadStatus(false);
 			return;
 		}
@@ -128,14 +127,12 @@ class LLWebProfileResponders::PostImageRedirectResponder : public LLHTTPClient::
 
 public:
 	/*virtual*/ void completedRaw(
-		U32 status,
-		const std::string& reason,
 		const LLChannelDescriptors& channels,
 		const LLIOPipe::buffer_ptr_t& buffer)
 	{
-		if (status != 200)
+		if (getStatus() != HTTP_OK)
 		{
-			llwarns << "Failed to upload image: " << status << " " << reason << llendl;
+			llwarns << "Failed to upload image " << dumpResponse() << llendl;
 			LLWebProfile::reportImageUploadStatus(false);
 			return;
 		}
@@ -161,33 +158,37 @@ class LLWebProfileResponders::PostImageResponder : public LLHTTPClient::Responde
 	LOG_CLASS(LLWebProfileResponders::PostImageResponder);
 
 public:
-	/*virtual*/ void completedHeader(U32 status, const std::string& reason, const LLSD& content)
+	/*virtual*/ void completedRaw(const LLChannelDescriptors& channels,
+								  const LLIOPipe::buffer_ptr_t& buffer)
 	{
 		// Viewer seems to fail to follow a 303 redirect on POST request
 		// (URLRequest Error: 65, Send failed since rewinding of the data stream failed).
 		// Handle it manually.
-		if (status == 303)
+		if (getStatus() == HTTP_SEE_OTHER)
 		{
 			LLSD headers = LLViewerMedia::getHeaders();
-			headers["Cookie"] = LLWebProfile::getAuthCookie();
-			const std::string& redir_url = content["location"];
-			LL_DEBUGS("Snapshots") << "Got redirection URL: " << redir_url << llendl;
-			LLHTTPClient::get(redir_url, new LLWebProfileResponders::PostImageRedirectResponder, headers);
+			headers[HTTP_HEADER_COOKIE] = LLWebProfile::getAuthCookie();
+			const bool check_lower=true;
+			const std::string& redir_url = getResponseHeader(HTTP_HEADER_LOCATION, check_lower);
+			if (redir_url.empty())
+			{
+				llwarns << "Received empty redirection URL " << dumpResponse() << llendl;
+				LL_DEBUGS("Snapshots") << "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
+				LLWebProfile::reportImageUploadStatus(false);
+			}
+			else
+			{
+				LL_DEBUGS("Snapshots") << "Got redirection URL: " << redir_url << llendl;
+				LLHTTPClient::get(redir_url, new LLWebProfileResponders::PostImageRedirectResponder, headers);
+			}
 		}
 		else
 		{
-			llwarns << "Unexpected POST status: " << status << " " << reason << llendl;
-			LL_DEBUGS("Snapshots") << "headers: [" << content << "]" << llendl;
+			llwarns << "Unexpected POST response " << dumpResponse() << llendl;
+			LL_DEBUGS("Snapshots") << "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
 			LLWebProfile::reportImageUploadStatus(false);
 		}
 	}
-
-	// Override just to suppress warnings.
-	/*virtual*/ void completedRaw(U32 status, const std::string& reason,
-							  const LLChannelDescriptors& channels,
-							  const LLIOPipe::buffer_ptr_t& buffer)
-	{
-	}
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -206,7 +207,7 @@ void LLWebProfile::uploadImage(LLPointer<LLImageFormatted> image, const std::str
 
 	LL_DEBUGS("Snapshots") << "Requesting " << config_url << llendl;
 	LLSD headers = LLViewerMedia::getHeaders();
-	headers["Cookie"] = getAuthCookie();
+	headers[HTTP_HEADER_COOKIE] = getAuthCookie();
 	LLHTTPClient::get(config_url, new LLWebProfileResponders::ConfigResponder(image), headers);
 }
 
@@ -230,8 +231,8 @@ void LLWebProfile::post(LLPointer<LLImageFormatted> image, const LLSD& config, c
 	const std::string boundary = "----------------------------0123abcdefab";
 
 	LLSD headers = LLViewerMedia::getHeaders();
-	headers["Cookie"] = getAuthCookie();
-	headers["Content-Type"] = "multipart/form-data; boundary=" + boundary;
+	headers[HTTP_HEADER_COOKIE] = getAuthCookie();
+	headers[HTTP_HEADER_CONTENT_TYPE] = "multipart/form-data; boundary=" + boundary;
 
 	std::ostringstream body;
 
diff --git a/indra/newview/llwebsharing.cpp b/indra/newview/llwebsharing.cpp
index 3a80051b9b7896a06ac604ae025d3d5750b23db3..ba536ac5823e5967dabcd6eb6995f43509751464 100644
--- a/indra/newview/llwebsharing.cpp
+++ b/indra/newview/llwebsharing.cpp
@@ -32,7 +32,7 @@
 #include "llagentui.h"
 #include "llbufferstream.h"
 #include "llhttpclient.h"
-#include "llhttpstatuscodes.h"
+#include "llhttpconstants.h"
 #include "llsdserialize.h"
 #include "llsdutil.h"
 #include "llurl.h"
@@ -45,36 +45,57 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 //
-class LLWebSharingConfigResponder : public LLHTTPClient::Responder
+
+class LLWebSharingJSONResponder : public LLHTTPClient::Responder
 {
-	LOG_CLASS(LLWebSharingConfigResponder);
+	LOG_CLASS(LLWebSharingJSONResponder);
 public:
 	/// Overrides the default LLSD parsing behaviour, to allow parsing a JSON response.
-	virtual void completedRaw(U32 status, const std::string& reason,
-							  const LLChannelDescriptors& channels,
+	virtual void completedRaw(const LLChannelDescriptors& channels,
 							  const LLIOPipe::buffer_ptr_t& buffer)
 	{
-		LLSD content;
 		LLBufferStream istr(channels, buffer.get());
 		LLPointer<LLSDParser> parser = new LLSDNotationParser();
 
-		if (parser->parse(istr, content, LLSDSerialize::SIZE_UNLIMITED) == LLSDParser::PARSE_FAILURE)
-		{
-			LL_WARNS("WebSharing") << "Failed to deserialize LLSD from JSON response. " << " [" << status << "]: " << reason << LL_ENDL;
-		}
-		else
+		if (parser->parse(istr, mContent, LLSDSerialize::SIZE_UNLIMITED) == LLSDParser::PARSE_FAILURE)
 		{
-			completed(status, reason, content);
+			if (HTTP_CONTENT_JSON == getResponseHeader(HTTP_HEADER_CONTENT_TYPE))
+			{
+				mStatus = HTTP_INTERNAL_ERROR;
+				mReason = "Failed to deserialize LLSD from JSON response.";
+				char body[1025]; 
+				body[1024] = '\0';
+				istr.seekg(0, std::ios::beg);
+				istr.get(body,1024);
+				if (strlen(body) > 0)
+				{
+					mContent["body"] = body;
+				}
+			}
 		}
+
+		httpCompleted();
 	}
+};
+
+class LLWebSharingConfigResponder : public LLWebSharingJSONResponder
+{
+	LOG_CLASS(LLWebSharingConfigResponder);
+private:
 
-	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+	virtual void httpFailure()
 	{
-		LL_WARNS("WebSharing") << "Error [status:" << status << "]: " << content << LL_ENDL;
+		LL_WARNS("WebSharing") << dumpResponse() << LL_ENDL;
 	}
 
-	virtual void result(const LLSD& content)
+	virtual void httpSuccess()
 	{
+		const LLSD& content = getContent();
+		if (!content.isMap())
+		{
+			failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+			return;
+		}
 		LLWebSharing::instance().receiveConfig(content);
 	}
 };
@@ -87,39 +108,35 @@ class LLWebSharingOpenIDAuthResponder : public LLHTTPClient::Responder
 {
 	LOG_CLASS(LLWebSharingOpenIDAuthResponder);
 public:
-	/* virtual */ void completedHeader(U32 status, const std::string& reason, const LLSD& content)
-	{
-		completed(status, reason, content);
-	}
-
-	/* virtual */ void completedRaw(U32 status, const std::string& reason,
-									const LLChannelDescriptors& channels,
+	/* virtual */ void completedRaw(const LLChannelDescriptors& channels,
 									const LLIOPipe::buffer_ptr_t& buffer)
 	{
 		/// Left empty to override the default LLSD parsing behaviour.
+		httpCompleted();
 	}
 
-	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+private:
+	virtual void httpFailure()
 	{
-		if (HTTP_UNAUTHORIZED == status)
+		if (HTTP_UNAUTHORIZED == getStatus())
 		{
 			LL_WARNS("WebSharing") << "AU account not authenticated." << LL_ENDL;
 			// *TODO: No account found on AU, so start the account creation process here.
 		}
 		else
 		{
-			LL_WARNS("WebSharing") << "Error [status:" << status << "]: " << content << LL_ENDL;
+			LL_WARNS("WebSharing") << dumpResponse() << LL_ENDL;
 			LLWebSharing::instance().retryOpenIDAuth();
 		}
-
 	}
 
-	virtual void result(const LLSD& content)
+	virtual void httpSuccess()
 	{
-		if (content.has("set-cookie"))
+		const bool check_lower=true;
+		if (hasResponseHeader(HTTP_HEADER_SET_COOKIE, check_lower))
 		{
 			// OpenID request succeeded and returned a session cookie.
-			LLWebSharing::instance().receiveSessionCookie(content["set-cookie"].asString());
+			LLWebSharing::instance().receiveSessionCookie(getResponseHeader(HTTP_HEADER_SET_COOKIE, check_lower));
 		}
 	}
 };
@@ -128,38 +145,19 @@ class LLWebSharingOpenIDAuthResponder : public LLHTTPClient::Responder
 
 ///////////////////////////////////////////////////////////////////////////////
 //
-class LLWebSharingSecurityTokenResponder : public LLHTTPClient::Responder
+class LLWebSharingSecurityTokenResponder : public LLWebSharingJSONResponder
 {
 	LOG_CLASS(LLWebSharingSecurityTokenResponder);
-public:
-	/// Overrides the default LLSD parsing behaviour, to allow parsing a JSON response.
-	virtual void completedRaw(U32 status, const std::string& reason,
-							  const LLChannelDescriptors& channels,
-							  const LLIOPipe::buffer_ptr_t& buffer)
+private:
+	virtual void httpFailure()
 	{
-		LLSD content;
-		LLBufferStream istr(channels, buffer.get());
-		LLPointer<LLSDParser> parser = new LLSDNotationParser();
-
-		if (parser->parse(istr, content, LLSDSerialize::SIZE_UNLIMITED) == LLSDParser::PARSE_FAILURE)
-		{
-			LL_WARNS("WebSharing") << "Failed to deserialize LLSD from JSON response. " << " [" << status << "]: " << reason << LL_ENDL;
-			LLWebSharing::instance().retryOpenIDAuth();
-		}
-		else
-		{
-			completed(status, reason, content);
-		}
-	}
-
-	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
-	{
-		LL_WARNS("WebSharing") << "Error [status:" << status << "]: " << content << LL_ENDL;
+		LL_WARNS("WebSharing") << dumpResponse() << LL_ENDL;
 		LLWebSharing::instance().retryOpenIDAuth();
 	}
 
-	virtual void result(const LLSD& content)
+	virtual void httpSuccess()
 	{
+		const LLSD& content = getContent();
 		if (content[0].has("st") && content[0].has("expires"))
 		{
 			const std::string& token   = content[0]["st"].asString();
@@ -172,7 +170,8 @@ class LLWebSharingSecurityTokenResponder : public LLHTTPClient::Responder
 		}
 		else
 		{
-			LL_WARNS("WebSharing") << "No security token received." << LL_ENDL;
+			failureResult(HTTP_INTERNAL_ERROR, "No security token received.", content);
+			return;
 		}
 
 		LLWebSharing::instance().retryOpenIDAuth();
@@ -183,51 +182,18 @@ class LLWebSharingSecurityTokenResponder : public LLHTTPClient::Responder
 
 ///////////////////////////////////////////////////////////////////////////////
 //
-class LLWebSharingUploadResponder : public LLHTTPClient::Responder
+class LLWebSharingUploadResponder : public LLWebSharingJSONResponder
 {
 	LOG_CLASS(LLWebSharingUploadResponder);
-public:
-	/// Overrides the default LLSD parsing behaviour, to allow parsing a JSON response.
-	virtual void completedRaw(U32 status, const std::string& reason,
-							  const LLChannelDescriptors& channels,
-							  const LLIOPipe::buffer_ptr_t& buffer)
-	{
-/*
-		 // Dump the body, for debugging.
-
-		 LLBufferStream istr1(channels, buffer.get());
-		 std::ostringstream ostr;
-		 std::string body;
-
-		 while (istr1.good())
-		 {
-			char buf[1024];
-			istr1.read(buf, sizeof(buf));
-			body.append(buf, istr1.gcount());
-		 }
-		 LL_DEBUGS("WebSharing") << body << LL_ENDL;
-*/
-		LLSD content;
-		LLBufferStream istr(channels, buffer.get());
-		LLPointer<LLSDParser> parser = new LLSDNotationParser();
-
-		if (parser->parse(istr, content, LLSDSerialize::SIZE_UNLIMITED) == LLSDParser::PARSE_FAILURE)
-		{
-			LL_WARNS("WebSharing") << "Failed to deserialize LLSD from JSON response. " << " [" << status << "]: " << reason << LL_ENDL;
-		}
-		else
-		{
-			completed(status, reason, content);
-		}
-	}
-
-	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+private:
+	virtual void httpFailure()
 	{
-		LL_WARNS("WebSharing") << "Error [status:" << status << "]: " << content << LL_ENDL;
+		LL_WARNS("WebSharing") << dumpResponse() << LL_ENDL;
 	}
 
-	virtual void result(const LLSD& content)
+	virtual void httpSuccess()
 	{
+		const LLSD& content = getContent();
 		if (content[0].has("result") && content[0].has("id") &&
 			content[0]["id"].asString() == "newMediaItem")
 		{
@@ -235,8 +201,8 @@ class LLWebSharingUploadResponder : public LLHTTPClient::Responder
 		}
 		else
 		{
-			LL_WARNS("WebSharing") << "Error [" << content[0]["code"].asString()
-								   << "]: " << content[0]["message"].asString() << LL_ENDL;
+			failureResult(HTTP_INTERNAL_ERROR, "Invalid response content", content);
+			return;
 		}
 	}
 };
@@ -333,7 +299,7 @@ void LLWebSharing::sendConfigRequest()
 	LL_DEBUGS("WebSharing") << "Requesting Snapshot Sharing config data from: " << config_url << LL_ENDL;
 
 	LLSD headers = LLSD::emptyMap();
-	headers["Accept"] = "application/json";
+	headers[HTTP_HEADER_ACCEPT] = HTTP_CONTENT_JSON;
 
 	LLHTTPClient::get(config_url, new LLWebSharingConfigResponder(), headers);
 }
@@ -344,8 +310,8 @@ void LLWebSharing::sendOpenIDAuthRequest()
 	LL_DEBUGS("WebSharing") << "Starting OpenID Auth: " << auth_url << LL_ENDL;
 
 	LLSD headers = LLSD::emptyMap();
-	headers["Cookie"] = mOpenIDCookie;
-	headers["Accept"] = "*/*";
+	headers[HTTP_HEADER_COOKIE] = mOpenIDCookie;
+	headers[HTTP_HEADER_ACCEPT] = "*/*";
 
 	// Send request, successful login will trigger fetching a security token.
 	LLHTTPClient::get(auth_url, new LLWebSharingOpenIDAuthResponder(), headers);
@@ -371,10 +337,10 @@ void LLWebSharing::sendSecurityTokenRequest()
 	LL_DEBUGS("WebSharing") << "Fetching security token from: " << token_url << LL_ENDL;
 
 	LLSD headers = LLSD::emptyMap();
-	headers["Cookie"] = mSessionCookie;
+	headers[HTTP_HEADER_COOKIE] = mSessionCookie;
 
-	headers["Accept"] = "application/json";
-	headers["Content-Type"] = "application/json";
+	headers[HTTP_HEADER_ACCEPT] = HTTP_CONTENT_JSON;
+	headers[HTTP_HEADER_CONTENT_TYPE] = HTTP_CONTENT_JSON;
 
 	std::ostringstream body;
 	body << "{ \"gadgets\": [{ \"url\":\""
@@ -400,10 +366,10 @@ void LLWebSharing::sendUploadRequest()
 	static const std::string BOUNDARY("------------abcdef012345xyZ");
 
 	LLSD headers = LLSD::emptyMap();
-	headers["Cookie"] = mSessionCookie;
+	headers[HTTP_HEADER_COOKIE] = mSessionCookie;
 
-	headers["Accept"] = "application/json";
-	headers["Content-Type"] = "multipart/form-data; boundary=" + BOUNDARY;
+	headers[HTTP_HEADER_ACCEPT] = HTTP_CONTENT_JSON;
+	headers[HTTP_HEADER_CONTENT_TYPE] = "multipart/form-data; boundary=" + BOUNDARY;
 
 	std::ostringstream body;
 	body << "--" << BOUNDARY << "\r\n"
diff --git a/indra/newview/llwlhandlers.cpp b/indra/newview/llwlhandlers.cpp
index 93eba5b6048aeddcf4552df38f76c295fee5eef0..3bedfbe502af09f22717da6c035bf5e8e7c47c96 100644
--- a/indra/newview/llwlhandlers.cpp
+++ b/indra/newview/llwlhandlers.cpp
@@ -95,8 +95,9 @@ LLEnvironmentRequestResponder::LLEnvironmentRequestResponder()
 {
 	mID = ++sCount;
 }
-/*virtual*/ void LLEnvironmentRequestResponder::result(const LLSD& unvalidated_content)
+/*virtual*/ void LLEnvironmentRequestResponder::httpSuccess()
 {
+	const LLSD& unvalidated_content = getContent();
 	LL_INFOS("WindlightCaps") << "Received region windlight settings" << LL_ENDL;
 
 	if (mID != sCount)
@@ -122,10 +123,10 @@ LLEnvironmentRequestResponder::LLEnvironmentRequestResponder()
 	LLEnvManagerNew::getInstance()->onRegionSettingsResponse(unvalidated_content);
 }
 /*virtual*/
-void LLEnvironmentRequestResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+void LLEnvironmentRequestResponder::httpFailure()
 {
-	LL_INFOS("WindlightCaps") << "Got an error, not using region windlight... [status:" 
-		<< status << "]: " << content << LL_ENDL;
+	LL_WARNS("WindlightCaps") << "Got an error, not using region windlight... "
+			<< dumpResponse() << LL_ENDL;
 	LLEnvManagerNew::getInstance()->onRegionSettingsResponse(LLSD());
 }
 
@@ -169,8 +170,14 @@ bool LLEnvironmentApply::initiateRequest(const LLSD& content)
 /****
  * LLEnvironmentApplyResponder
  ****/
-/*virtual*/ void LLEnvironmentApplyResponder::result(const LLSD& content)
+/*virtual*/ void LLEnvironmentApplyResponder::httpSuccess()
 {
+	const LLSD& content = getContent();
+	if (!content.isMap() || !content.has("regionID"))
+	{
+		failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+		return;
+	}
 	if (content["regionID"].asUUID() != gAgent.getRegion()->getRegionID())
 	{
 		LL_WARNS("WindlightCaps") << "No longer in the region where data was sent (currently "
@@ -185,7 +192,7 @@ bool LLEnvironmentApply::initiateRequest(const LLSD& content)
 	}
 	else
 	{
-		LL_WARNS("WindlightCaps") << "Region couldn't apply windlight settings!  Reason from sim: " << content["fail_reason"].asString() << LL_ENDL;
+		LL_WARNS("WindlightCaps") << "Region couldn't apply windlight settings!  " << dumpResponse() << LL_ENDL;
 		LLSD args(LLSD::emptyMap());
 		args["FAIL_REASON"] = content["fail_reason"].asString();
 		LLNotificationsUtil::add("WLRegionApplyFail", args);
@@ -193,14 +200,14 @@ bool LLEnvironmentApply::initiateRequest(const LLSD& content)
 	}
 }
 /*virtual*/
-void LLEnvironmentApplyResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+void LLEnvironmentApplyResponder::httpFailure()
 {
-	LL_WARNS("WindlightCaps") << "Couldn't apply windlight settings to region!  [status:"
-		<< status << "]: " << content << LL_ENDL;
+	LL_WARNS("WindlightCaps") << "Couldn't apply windlight settings to region! "
+		<< dumpResponse() << LL_ENDL;
 
 	LLSD args(LLSD::emptyMap());
 	std::stringstream msg;
-	msg << reason << " (Code " << status << ")";
+	msg << getReason() << " (Code " << getStatus() << ")";
 	args["FAIL_REASON"] = msg.str();
 	LLNotificationsUtil::add("WLRegionApplyFail", args);
 }
diff --git a/indra/newview/llwlhandlers.h b/indra/newview/llwlhandlers.h
index 598ce6d52ac52c6c54989ce6d5498237564b92b5..089c799da7cac21dd37228c41411fe0acd7854f4 100644
--- a/indra/newview/llwlhandlers.h
+++ b/indra/newview/llwlhandlers.h
@@ -45,9 +45,9 @@ class LLEnvironmentRequest
 class LLEnvironmentRequestResponder: public LLHTTPClient::Responder
 {
 	LOG_CLASS(LLEnvironmentRequestResponder);
-public:
-	virtual void result(const LLSD& content);
-	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
+private:
+	/* virtual */ void httpSuccess();
+	/* virtual */ void httpFailure();
 
 private:
 	friend class LLEnvironmentRequest;
@@ -72,7 +72,7 @@ class LLEnvironmentApply
 class LLEnvironmentApplyResponder: public LLHTTPClient::Responder
 {
 	LOG_CLASS(LLEnvironmentApplyResponder);
-public:
+private:
 	/*
 	 * Expecting reply from sim in form of:
 	 * {
@@ -87,10 +87,10 @@ class LLEnvironmentApplyResponder: public LLHTTPClient::Responder
 	 *   fail_reason : string
 	 * }
 	 */
-	virtual void result(const LLSD& content);
+	/* virtual */ void httpSuccess();
 
-	// non-200 errors only
-	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
+	// non-2xx errors only
+	/* virtual */ void httpFailure();
 
 private:
 	friend class LLEnvironmentApply;
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index 0da70d398b06ca0b35e50a7c40cc737b3efa1491..604e08161e3034638b54387ef6d7fb4e1761de9f 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -331,7 +331,7 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip)
 	   This might help with bug #503 */
 	mCurlRequest->setopt(CURLOPT_DNS_CACHE_TIMEOUT, -1);
 
-    mCurlRequest->slist_append("Content-Type: text/xml");
+    mCurlRequest->slist_append(HTTP_HEADER_CONTENT_TYPE, HTTP_CONTENT_TEXT_XML);
 
 	if (useGzip)
 	{
diff --git a/indra/newview/tests/llmediadataclient_test.cpp b/indra/newview/tests/llmediadataclient_test.cpp
index 41cb344808371cf9dc9c87fe31c28b7f09a9782d..01195d1269b5fae8db3240f8e17e296162cb0136 100644
--- a/indra/newview/tests/llmediadataclient_test.cpp
+++ b/indra/newview/tests/llmediadataclient_test.cpp
@@ -33,7 +33,7 @@
 #include "llsdserialize.h"
 #include "llsdutil.h"
 #include "llerrorcontrol.h"
-#include "llhttpstatuscodes.h"
+#include "llhttpconstants.h"
 
 #include "../llmediadataclient.h"
 #include "../llvovolume.h"
@@ -128,7 +128,7 @@ void LLHTTPClient::post(
 	{
 		LLSD content;
 		content["reason"] = "fake reason";
-		responder->errorWithContent(HTTP_SERVICE_UNAVAILABLE, "fake reason", content);
+		responder->failureResult(HTTP_SERVICE_UNAVAILABLE, "fake reason", content);
 		return;
 	}
 	else if (url == FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL_ERROR) 
@@ -136,8 +136,8 @@ void LLHTTPClient::post(
 		LLSD error;
 		error["code"] = LLObjectMediaNavigateClient::ERROR_PERMISSION_DENIED_CODE;
 		result["error"] = error;
-	}	
-	responder->result(result);
+	}
+	responder->successResult(result);
 }
 
 const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f;
diff --git a/indra/newview/tests/llremoteparcelrequest_test.cpp b/indra/newview/tests/llremoteparcelrequest_test.cpp
index ed66066b0ad840f97dc044d79c2b9396b0dac239..c49b0350e9b279925145c3674de7861cbd8a9297 100644
--- a/indra/newview/tests/llremoteparcelrequest_test.cpp
+++ b/indra/newview/tests/llremoteparcelrequest_test.cpp
@@ -40,12 +40,14 @@ namespace {
 
 LLCurl::Responder::Responder() { }
 LLCurl::Responder::~Responder() { }
-void LLCurl::Responder::error(U32,std::string const &) { }
-void LLCurl::Responder::result(LLSD const &) { }
-void LLCurl::Responder::errorWithContent(U32 status,std::string const &,LLSD const &) { }
-void LLCurl::Responder::completedRaw(U32 status, std::string const &, LLChannelDescriptors const &,boost::shared_ptr<LLBufferArray> const &) { }
-void LLCurl::Responder::completed(U32 status, std::string const &, LLSD const &) { }
-void LLCurl::Responder::completedHeader(U32 status, std::string const &, LLSD const &) { }
+void LLCurl::Responder::httpFailure() { }
+void LLCurl::Responder::httpSuccess() { }
+void LLCurl::Responder::httpCompleted() { }
+void LLCurl::Responder::failureResult(S32 status, const std::string& reason, const LLSD& content) { }
+void LLCurl::Responder::successResult(const LLSD& content) { }
+void LLCurl::Responder::completeResult(S32 status, const std::string& reason, const LLSD& content) { }
+std::string LLCurl::Responder::dumpResponse() const { return "(failure)"; }
+void LLCurl::Responder::completedRaw(LLChannelDescriptors const &,boost::shared_ptr<LLBufferArray> const &) { }
 void LLMessageSystem::getF32(char const *,char const *,F32 &,S32) { }
 void LLMessageSystem::getU8(char const *,char const *,U8 &,S32) { }
 void LLMessageSystem::getS32(char const *,char const *,S32 &,S32) { }
@@ -85,7 +87,7 @@ namespace tut
 
 		virtual void setParcelID(const LLUUID& parcel_id) { }
 
-		virtual void setErrorStatus(U32 status, const std::string& reason) { }
+		virtual void setErrorStatus(S32 status, const std::string& reason) { }
 
 		bool mProcessed;
 	};
diff --git a/indra/newview/tests/lltranslate_test.cpp b/indra/newview/tests/lltranslate_test.cpp
index fd9527d631a921ce957e8b41e1b56a1c98ec4123..b28eb5db435d1e055982c3cf9d5ba4d0a918493a 100644
--- a/indra/newview/tests/lltranslate_test.cpp
+++ b/indra/newview/tests/lltranslate_test.cpp
@@ -34,6 +34,8 @@
 #include "lltrans.h"
 #include "llui.h"
 
+#include "../../llmessage/llhttpconstants.cpp"
+
 static const std::string GOOGLE_VALID_RESPONSE1 =
 "{\
  \"data\": {\
@@ -300,12 +302,10 @@ std::string LLControlGroup::getString(const std::string& name) { return "dummy";
 LLControlGroup::~LLControlGroup() {}
 
 LLCurl::Responder::Responder() {}
-void LLCurl::Responder::completedHeader(U32, std::string const&, LLSD const&) {}
-void LLCurl::Responder::completedRaw(U32, const std::string&, const LLChannelDescriptors&, const LLIOPipe::buffer_ptr_t& buffer) {}
-void LLCurl::Responder::completed(U32, std::string const&, LLSD const&) {}
-void LLCurl::Responder::error(U32, std::string const&) {}
-void LLCurl::Responder::errorWithContent(U32, std::string const&, LLSD const&) {}
-void LLCurl::Responder::result(LLSD const&) {}
+void LLCurl::Responder::httpFailure() { }
+void LLCurl::Responder::httpSuccess() { }
+void LLCurl::Responder::httpCompleted() { }
+void LLCurl::Responder::completedRaw(LLChannelDescriptors const &,boost::shared_ptr<LLBufferArray> const &) { }
 LLCurl::Responder::~Responder() {}
 
 void LLHTTPClient::get(const std::string&, const LLSD&, ResponderPtr, const LLSD&, const F32) {}
diff --git a/indra/test/llassetuploadqueue_tut.cpp b/indra/test/llassetuploadqueue_tut.cpp
index ec952e0058c47aa0224066f4f53913f408161f87..25efe63d3fa84d41f43be6a497b46b915958c4cc 100644
--- a/indra/test/llassetuploadqueue_tut.cpp
+++ b/indra/test/llassetuploadqueue_tut.cpp
@@ -45,11 +45,11 @@ LLAssetUploadResponder::~LLAssetUploadResponder()
 {
 }
 
-void LLAssetUploadResponder::error(U32 statusNum, const std::string& reason)
+void LLAssetUploadResponder::httpFailure()
 {
 }
 
-void LLAssetUploadResponder::result(const LLSD& content)
+void LLAssetUploadResponder::httpSuccess()
 {
 }
 
diff --git a/indra/test/llblowfish_tut.cpp b/indra/test/llblowfish_tut.cpp
index 2573cab81faf5cae056677098d1a51d0746742b3..20e7960829f4a7f6269a69359c4dbdc615d47de9 100644
--- a/indra/test/llblowfish_tut.cpp
+++ b/indra/test/llblowfish_tut.cpp
@@ -65,7 +65,7 @@ namespace tut
 			}
 			if (!fp)
 			{
-				llwarns << "unabled to open " << filename << llendl;
+				llwarns << "unable to open " << filename << llendl;
 				return false;
 			}
 
diff --git a/indra/test/llhttpnode_tut.cpp b/indra/test/llhttpnode_tut.cpp
index 216c59d766de0620f73e62c472c3beb02a16e2c7..d5802631030eb0a0d2c56644ce77c006535f0cd7 100644
--- a/indra/test/llhttpnode_tut.cpp
+++ b/indra/test/llhttpnode_tut.cpp
@@ -81,6 +81,7 @@ namespace tut
 			void result(const LLSD& result) { mResult = result; }
 			void status(S32 code, const std::string& message) { }
 			void extendedResult(S32 code, const std::string& message, const LLSD& headers) { }
+			void extendedResult(S32 code, const LLSD& result, const LLSD& headers) { }
 			
 		private:
 			Response() {;} // Must be accessed through LLPointer.
diff --git a/indra/test/llsd_new_tut.cpp b/indra/test/llsd_new_tut.cpp
index f928a1bad0e6176af82a175428298f3b4f637ad4..03df1d339bc4f1856e3decdb97847a845fc6530d 100644
--- a/indra/test/llsd_new_tut.cpp
+++ b/indra/test/llsd_new_tut.cpp
@@ -93,6 +93,18 @@ namespace tut
 			ensure(			s + " type",	traits.checkType(actual));
 			ensure_equals(	s + " value",	traits.get(actual), expectedValue);
 		}
+
+		template<class T>
+		static void ensureTypeAndRefValue(const char* msg, const LLSD& actual,
+			const T& expectedValue)
+		{
+			LLSDTraits<const T&> traits;
+			
+			std::string s(msg);
+			
+			ensure(			s + " type",	traits.checkType(actual));
+			ensure_equals(	s + " value",	traits.get(actual), expectedValue);
+		}
 	};
 	
 	typedef test_group<SDTestData>	SDTestGroup;
@@ -162,7 +174,7 @@ namespace tut
 		std::vector<U8> data;
 		copy(&source[0], &source[sizeof(source)], back_inserter(data));
 		
-		v = data;		ensureTypeAndValue("set to data", v, data);
+		v = data;		ensureTypeAndRefValue("set to data", v, data);
 		
 		v.clear();
 		ensure("reset to undefined", v.type() == LLSD::TypeUndefined);
@@ -213,8 +225,8 @@ namespace tut
 		const char source[] = "once in a blue moon";
 		std::vector<U8> data;
 		copy(&source[0], &source[sizeof(source)], back_inserter(data));
-		LLSD x1(data);	ensureTypeAndValue("construct vector<U8>", x1, data);
-		LLSD x2 = data;	ensureTypeAndValue("initialize vector<U8>", x2, data);
+		LLSD x1(data);	ensureTypeAndRefValue("construct vector<U8>", x1, data);
+		LLSD x2 = data;	ensureTypeAndRefValue("initialize vector<U8>", x2, data);
 	}
 	
 	void checkConversions(const char* msg, const LLSD& v,
@@ -754,42 +766,6 @@ namespace tut
 			w = "nice day";
 		}
 
-		{
-			SDAllocationCheck check("shared values test for threaded work", 9);
-
-			//U32 start_llsd_count = llsd::outstandingCount();
-
-			LLSD m = LLSD::emptyMap();
-
-			m["one"] = 1;
-			m["two"] = 2;
-			m["one_copy"] = m["one"];			// 3 (m, "one" and "two")
-
-			m["undef_one"] = LLSD();
-			m["undef_two"] = LLSD();
-			m["undef_one_copy"] = m["undef_one"];
-
-			{	// Ensure first_array gets freed to avoid counting it
-				LLSD first_array = LLSD::emptyArray();
-				first_array.append(1.0f);
-				first_array.append(2.0f);			
-				first_array.append(3.0f);			// 7
-
-				m["array"] = first_array;
-				m["array_clone"] = first_array;
-				m["array_copy"] = m["array"];		// 7
-			}
-
-			m["string_one"] = "string one value";
-			m["string_two"] = "string two value";
-			m["string_one_copy"] = m["string_one"];		// 9
-
-			//U32 llsd_object_count = llsd::outstandingCount();
-			//std::cout << "Using " << (llsd_object_count - start_llsd_count) << " LLSD objects" << std::endl;
-
-			//m.dumpStats();
-		}
-
 		{
 			SDAllocationCheck check("shared values test for threaded work", 9);
 
@@ -852,3 +828,4 @@ namespace tut
 		test serializations
 	*/
 }
+
diff --git a/indra/test/llsdtraits.h b/indra/test/llsdtraits.h
index 8144aaee948924dde8ab43e659ec6f1e2cefd888..07f6193ce247fdd98ce797964dcc3c8eaa42702e 100644
--- a/indra/test/llsdtraits.h
+++ b/indra/test/llsdtraits.h
@@ -93,7 +93,7 @@ LLSDTraits<LLSD::URI>::LLSDTraits()
 { }
 
 template<> inline
-LLSDTraits<LLSD::Binary>::LLSDTraits()
+LLSDTraits<const LLSD::Binary&>::LLSDTraits()
 	: type(LLSD::TypeBinary), getter(&LLSD::asBinary)
 { }
 
diff --git a/indra/test/message_tut.cpp b/indra/test/message_tut.cpp
index d971b334752dc1c99e5c7bc80d62f84430a62a10..0dae5178be2a4266d114bcdf8946b41b5b6263ca 100644
--- a/indra/test/message_tut.cpp
+++ b/indra/test/message_tut.cpp
@@ -46,6 +46,7 @@ namespace
 			mStatus = code;
 		}
 		virtual void extendedResult(S32 code, const std::string& message, const LLSD& headers) { }
+		virtual void extendedResult(S32 code, const LLSD& result, const LLSD& headers) { }
 		S32 mStatus;
 	};
 }
@@ -142,7 +143,7 @@ namespace tut
 		const LLSD message;
 		const LLPointer<Response> response = new Response();
 		gMessageSystem->dispatch(name, message, response);
-		ensure_equals(response->mStatus, 404);
+		ensure_equals(response->mStatus, HTTP_NOT_FOUND);
 	}
 }
 
diff --git a/indra/test/mock_http_client.h b/indra/test/mock_http_client.h
index 7668a43fdf94ebc58a9d51aac09910c9c450527b..a2b9b435fb1db995e0108cbc65bcb6c1923b2b86 100644
--- a/indra/test/mock_http_client.h
+++ b/indra/test/mock_http_client.h
@@ -98,7 +98,7 @@ namespace tut
 			if (mSawError)
 			{
 				std::string msg =
-					llformat("error() called when not expected, status %d",
+					llformat("httpFailure() called when not expected, status %d",
 						mStatus); 
 				fail(msg);
 			}
@@ -108,7 +108,7 @@ namespace tut
 		{
 			if (!mSawError)
 			{
-				fail("error() wasn't called");
+				fail("httpFailure() wasn't called");
 			}
 		}
 		
@@ -119,7 +119,7 @@ namespace tut
 	
 	protected:
 		bool mSawError;
-		U32 mStatus;
+		S32 mStatus;
 		std::string mReason;
 		bool mSawCompleted;
 		LLSD mResult;
@@ -144,23 +144,22 @@ namespace tut
 				mClient.mResultDeleted = true;
 			}
 			
-			virtual void error(U32 status, const std::string& reason)
+		protected:
+			virtual void httpFailure()
 			{
 				mClient.mSawError = true;
-				mClient.mStatus = status;
-				mClient.mReason = reason;
+				mClient.mStatus = getStatus();
+				mClient.mReason = getReason();
 			}
 
-			virtual void result(const LLSD& content)
+			virtual void httpSuccess()
 			{
-				mClient.mResult = content;
+				mClient.mResult = getContent();
 			}
 
-			virtual void completed(
-							U32 status, const std::string& reason,
-							const LLSD& content)
+			virtual void httpCompleted()
 			{
-				LLHTTPClient::Responder::completed(status, reason, content);
+				LLHTTPClient::Responder::httpCompleted();
 				
 				mClient.mSawCompleted = true;
 			}
diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp
index 5edbbf9914cbfb7ae52f17f24cade54377e8ba91..49b404a7adf0ebb2be9b2736fe34f15db57adf53 100644
--- a/indra/viewer_components/updater/llupdatechecker.cpp
+++ b/indra/viewer_components/updater/llupdatechecker.cpp
@@ -106,15 +106,14 @@ void LLUpdateChecker::Implementation::checkVersion(std::string const & protocolV
 	mHttpClient.get(checkUrl, this);
 }
 
-void LLUpdateChecker::Implementation::completed(U32 status,
-							  const std::string & reason,
-							  const LLSD & content)
+void LLUpdateChecker::Implementation::httpCompleted()
 {
-	mInProgress = false;	
-	
-	if(status != 200) {
-		LL_WARNS("UpdateCheck") << "html error " << status << " (" << reason << ")" << llendl;
-		mClient.error(reason);
+	mInProgress = false;
+
+	const LLSD& content = getContent();
+	if(getStatus() != HTTP_OK) {
+		LL_WARNS("UpdateCheck") << "html error " << dumpResponse() << LL_ENDL;
+		mClient.error(getReason());
 	} else if(!content.asBoolean()) {
 		LL_INFOS("UpdateCheck") << "up to date" << llendl;
 		mClient.upToDate();
@@ -130,8 +129,9 @@ void LLUpdateChecker::Implementation::completed(U32 status,
 }
 
 
-void LLUpdateChecker::Implementation::error(U32 status, const std::string & reason)
+void LLUpdateChecker::Implementation::httpFailure()
 {
+	const std::string& reason = getReason();
 	mInProgress = false;
 	LL_WARNS("UpdateCheck") << "update check failed; " << reason << llendl;
 	mClient.error(reason);
diff --git a/indra/viewer_components/updater/llupdatechecker.h b/indra/viewer_components/updater/llupdatechecker.h
index 23f62a7c5eee98b265e99935cad6edc2f8425f98..3ecd6230be9d47336903009eb197dc8f0df9bf38 100644
--- a/indra/viewer_components/updater/llupdatechecker.h
+++ b/indra/viewer_components/updater/llupdatechecker.h
@@ -47,11 +47,10 @@ class LLUpdateChecker {
 		void checkVersion(std::string const & protocolVersion, std::string const & hostUrl, 
 				   std::string const & servicePath, std::string channel, std::string version);
 	
+    protected:
 		// Responder:
-		virtual void completed(U32 status,
-							   const std::string & reason,
-							   const LLSD& content);
-		virtual void error(U32 status, const std::string & reason);
+		virtual void httpCompleted();
+		virtual void httpFailure();
 	
 	private:	
 		static const char * sProtocolVersion;