From 66739da16407a8e56accc236bd3996c1963a6bcf Mon Sep 17 00:00:00 2001
From: Aaron Brashears <aaronb@lindenlab.com>
Date: Mon, 29 Sep 2008 17:41:54 +0000
Subject: Result of svn merge -r97546:97641
 svn+ssh://svn/svn/linden/branches/apache-caps/merge-to-release into release.
 QAR-824

---
 indra/lib/python/indra/base/llsd.py    | 56 ++++++++++++++++++++++++++++++++--
 indra/lib/python/indra/ipc/llsdhttp.py |  2 ++
 indra/lib/python/indra/ipc/siesta.py   |  4 +--
 indra/llmessage/llcurl.cpp             |  2 +-
 indra/llmessage/llhttpclient.cpp       | 33 ++++++++++++++++----
 indra/llmessage/lliohttpserver.cpp     |  2 +-
 indra/test/lliohttpserver_tut.cpp      |  4 +--
 7 files changed, 88 insertions(+), 15 deletions(-)

(limited to 'indra')

diff --git a/indra/lib/python/indra/base/llsd.py b/indra/lib/python/indra/base/llsd.py
index 521b79c65a..17ab89004a 100644
--- a/indra/lib/python/indra/base/llsd.py
+++ b/indra/lib/python/indra/base/llsd.py
@@ -969,6 +969,9 @@ class LLSD(object):
 
 undef = LLSD(None)
 
+XML_MIME_TYPE = 'application/llsd+xml'
+BINARY_MIME_TYPE = 'application/llsd+binary'
+
 # register converters for llsd in mulib, if it is available
 try:
     from mulib import stacked, mu
@@ -978,7 +981,7 @@ except:
     # mulib not available, don't print an error message since this is normal
     pass
 else:
-    mu.add_parser(parse, 'application/llsd+xml')
+    mu.add_parser(parse, XML_MIME_TYPE)
     mu.add_parser(parse, 'application/llsd+binary')
 
     def llsd_convert_xml(llsd_stuff, request):
@@ -987,11 +990,58 @@ else:
     def llsd_convert_binary(llsd_stuff, request):
         request.write(format_binary(llsd_stuff))
 
-    for typ in [LLSD, dict, list, tuple, str, int, float, bool, unicode, type(None)]:
-        stacked.add_producer(typ, llsd_convert_xml, 'application/llsd+xml')
+    for typ in [LLSD, dict, list, tuple, str, int, long, float, bool, unicode, type(None)]:
+        stacked.add_producer(typ, llsd_convert_xml, XML_MIME_TYPE)
         stacked.add_producer(typ, llsd_convert_xml, 'application/xml')
         stacked.add_producer(typ, llsd_convert_xml, 'text/xml')
 
         stacked.add_producer(typ, llsd_convert_binary, 'application/llsd+binary')
 
     stacked.add_producer(LLSD, llsd_convert_xml, '*/*')
+
+    # in case someone is using the legacy mu.xml wrapper, we need to
+    # tell mu to produce application/xml or application/llsd+xml
+    # (based on the accept header) from raw xml. Phoenix 2008-07-21
+    stacked.add_producer(mu.xml, mu.produce_raw, XML_MIME_TYPE)
+    stacked.add_producer(mu.xml, mu.produce_raw, 'application/xml')
+
+
+
+# mulib wsgi stuff
+# try:
+#     from mulib import mu, adapters
+#
+#     # try some known attributes from mulib to be ultra-sure we've imported it
+#     mu.get_current
+#     adapters.handlers
+# except:
+#     # mulib not available, don't print an error message since this is normal
+#     pass
+# else:
+#     def llsd_xml_handler(content_type):
+#         def handle_llsd_xml(env, start_response):
+#             llsd_stuff, _ = mu.get_current(env)
+#             result = format_xml(llsd_stuff)
+#             start_response("200 OK", [('Content-Type', content_type)])
+#             env['mu.negotiated_type'] = content_type
+#             yield result
+#         return handle_llsd_xml
+#    
+#     def llsd_binary_handler(content_type):
+#         def handle_llsd_binary(env, start_response):
+#             llsd_stuff, _ = mu.get_current(env)
+#             result = format_binary(llsd_stuff)
+#             start_response("200 OK", [('Content-Type', content_type)])
+#             env['mu.negotiated_type'] = content_type
+#             yield result
+#         return handle_llsd_binary
+#
+#     adapters.DEFAULT_PARSERS[XML_MIME_TYPE] = parse
+    
+#     for typ in [LLSD, dict, list, tuple, str, int, float, bool, unicode, type(None)]:
+#         for content_type in (XML_MIME_TYPE, 'application/xml'):
+#             adapters.handlers.set_handler(typ, llsd_xml_handler(content_type), content_type)
+#
+#         adapters.handlers.set_handler(typ, llsd_binary_handler(BINARY_MIME_TYPE), BINARY_MIME_TYPE)
+#
+#     adapters.handlers.set_handler(LLSD, llsd_xml_handler(XML_MIME_TYPE), '*/*')
diff --git a/indra/lib/python/indra/ipc/llsdhttp.py b/indra/lib/python/indra/ipc/llsdhttp.py
index c45489643e..ea4608c82b 100644
--- a/indra/lib/python/indra/ipc/llsdhttp.py
+++ b/indra/lib/python/indra/ipc/llsdhttp.py
@@ -51,6 +51,8 @@ request_ = suite.request_
 # import every httpc error exception into our namespace for convenience
 for x in httpc.status_to_error_map.itervalues():
     globals()[x.__name__] = x
+ConnectionError = httpc.ConnectionError
+Retriable = httpc.Retriable
 
 for x in (httpc.ConnectionError,):
     globals()[x.__name__] = x
diff --git a/indra/lib/python/indra/ipc/siesta.py b/indra/lib/python/indra/ipc/siesta.py
index 5fbea29339..b206f181c4 100644
--- a/indra/lib/python/indra/ipc/siesta.py
+++ b/indra/lib/python/indra/ipc/siesta.py
@@ -24,9 +24,9 @@ except ImportError:
 
 llsd_parsers = {
     'application/json': json_decode,
-    'application/llsd+binary': llsd.parse_binary,
+    llsd.BINARY_MIME_TYPE: llsd.parse_binary,
     'application/llsd+notation': llsd.parse_notation,
-    'application/llsd+xml': llsd.parse_xml,
+    llsd.XML_MIME_TYPE: llsd.parse_xml,
     'application/xml': llsd.parse_xml,
     }
 
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index 8c7392090c..1107945b56 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -751,7 +751,7 @@ bool LLCurlRequest::post(const std::string& url, const LLSD& data, LLCurl::Respo
 	easy->setopt(CURLOPT_POSTFIELDS, (void*)NULL);
 	easy->setopt(CURLOPT_POSTFIELDSIZE, bytes);
 
-	easy->slist_append("Content-Type: application/xml");
+	easy->slist_append("Content-Type: application/llsd+xml");
 	easy->setHeaders();
 
 	lldebugs << "POSTING: " << bytes << " bytes." << llendl;
diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp
index 2f822aee87..5bf0c08e67 100644
--- a/indra/llmessage/llhttpclient.cpp
+++ b/indra/llmessage/llhttpclient.cpp
@@ -106,7 +106,7 @@ namespace
 		LLSDInjector(const LLSD& sd) : mSD(sd) {}
 		virtual ~LLSDInjector() {}
 
-		const char* contentType() { return "application/xml"; }
+		const char* contentType() { return "application/llsd+xml"; }
 
 		virtual EStatus process_impl(const LLChannelDescriptors& channels,
 			buffer_ptr_t& buffer, bool& eos, LLSD& context, LLPumpIO* pump)
@@ -238,7 +238,8 @@ static void request(
             //the Pragma header it so gratuitously inserts
             //Before inserting the header, force libcurl
             //to not use the proxy (read: llurlrequest.cpp)
-            if ((iter->first == "Pragma") && (iter->second.asString() == ""))
+			static const std::string PRAGMA("Pragma");
+			if ((iter->first == PRAGMA) && (iter->second.asString().empty()))
             {
                 req->useProxy(false);
             }
@@ -247,6 +248,16 @@ static void request(
             req->addHeader(header.str().c_str());
         }
     }
+
+	// 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.
+	static const std::string ACCEPT("Accept");
+	if(!headers.has(ACCEPT))
+	{
+		req->addHeader("Accept: application/llsd+xml");
+	}
+
 	req->setCallback(new LLHTTPClientURLAdaptor(responder));
 
 	if (method == LLURLRequest::HTTP_POST  &&  gMessageSystem)
@@ -254,12 +265,22 @@ static void request(
 		req->addHeader(llformat("X-SecondLife-UDP-Listen-Port: %d",
 								gMessageSystem->mPort).c_str());
    	}
-	
+
 	if (method == LLURLRequest::HTTP_PUT || method == LLURLRequest::HTTP_POST)
 	{
-		req->addHeader(llformat("Content-Type: %s",
-								body_injector->contentType()).c_str());
-
+		static const std::string CONTENT_TYPE("Content-Type");
+		if(!headers.has(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());
+		}
    		chain.push_back(LLIOPipe::ptr_t(body_injector));
 	}
 
diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp
index a2e0325ae7..6d157206c8 100644
--- a/indra/llmessage/lliohttpserver.cpp
+++ b/indra/llmessage/lliohttpserver.cpp
@@ -240,7 +240,7 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
 		case STATE_GOOD_RESULT:
 		{
 			LLSD headers = mHeaders;
-			headers["Content-Type"] = "application/xml";
+			headers["Content-Type"] = "application/llsd+xml";
 			context[CONTEXT_RESPONSE][CONTEXT_HEADERS] = headers;
 			LLBufferStream ostr(channels, buffer.get());
 			LLSDSerialize::toXML(mGoodResult, ostr);
diff --git a/indra/test/lliohttpserver_tut.cpp b/indra/test/lliohttpserver_tut.cpp
index e5607cdad7..72d7936f20 100644
--- a/indra/test/lliohttpserver_tut.cpp
+++ b/indra/test/lliohttpserver_tut.cpp
@@ -191,7 +191,7 @@ namespace tut
 			"HTTP/1.0 200 OK\r\n");
 						
 		ensure_contains("web/hello content type", result,
-			"Content-Type: application/xml\r\n");
+			"Content-Type: application/llsd+xml\r\n");
 
 		ensure_contains("web/hello content length", result,
 			"Content-Length: 36\r\n");
@@ -232,7 +232,7 @@ namespace tut
 			"HTTP/1.0 200 OK\r\n");
 						
 		ensure_contains("web/echo content type", result,
-			"Content-Type: application/xml\r\n");
+			"Content-Type: application/llsd+xml\r\n");
 
 		ensure_contains("web/echo content length", result,
 			"Content-Length: 35\r\n");
-- 
cgit v1.2.3