summaryrefslogtreecommitdiff
path: root/indra/llmessage
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llmessage')
-rwxr-xr-xindra/llmessage/CMakeLists.txt15
-rwxr-xr-xindra/llmessage/llavatarnamecache.cpp286
-rwxr-xr-xindra/llmessage/llavatarnamecache.h5
-rw-r--r--indra/llmessage/llcorehttputil.cpp168
-rw-r--r--indra/llmessage/llcorehttputil.h87
-rwxr-xr-xindra/llmessage/llcurl.cpp858
-rwxr-xr-xindra/llmessage/llcurl.h96
-rwxr-xr-xindra/llmessage/llhttpclient.cpp4
-rwxr-xr-xindra/llmessage/llhttpclientadapter.cpp90
-rwxr-xr-xindra/llmessage/llhttpclientadapter.h2
-rwxr-xr-xindra/llmessage/llhttpclientinterface.h16
-rw-r--r--indra/llmessage/llhttpsdhandler.cpp103
-rw-r--r--indra/llmessage/llhttpsdhandler.h67
-rwxr-xr-xindra/llmessage/llsdrpcclient.h8
-rwxr-xr-xindra/llmessage/tests/llhttpclientadapter_test.cpp3
15 files changed, 1136 insertions, 672 deletions
diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt
index 40eddcb0ab..f6ca6a3634 100755
--- a/indra/llmessage/CMakeLists.txt
+++ b/indra/llmessage/CMakeLists.txt
@@ -49,6 +49,7 @@ set(llmessage_SOURCE_FILES
llhttpclientadapter.cpp
llhttpconstants.cpp
llhttpnode.cpp
+ llhttpsdhandler.cpp
llhttpsender.cpp
llinstantmessage.cpp
lliobuffer.cpp
@@ -144,6 +145,7 @@ set(llmessage_HEADER_FILES
llhttpconstants.h
llhttpnode.h
llhttpnodeadapter.h
+ llhttpsdhandler.h
llhttpsender.h
llinstantmessage.h
llinvite.h
@@ -224,7 +226,7 @@ target_link_libraries(
llmessage
${CURL_LIBRARIES}
${LLCOMMON_LIBRARIES}
- ${LLVFS_LIBRARES}
+ ${LLVFS_LIBRARIES}
${LLMATH_LIBRARIES}
${CARES_LIBRARIES}
${OPENSSL_LIBRARIES}
@@ -241,15 +243,20 @@ if (LL_TESTS)
)
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}
${LLMATH_LIBRARIES}
+ ${CURL_LIBRARIES}
${LLCOMMON_LIBRARIES}
- ${GOOGLEMOCK_LIBRARIES}
+ ${LLMESSAGE_LIBRARIES}
+ ${LLCOREHTTP_LIBRARIES}
+ ${BOOST_CONTEXT_LIBRARY}
+ ${BOOST_COROUTINE_LIBRARY}
+ ${GOOGLEMOCK_LIBRARIES}
)
LL_ADD_INTEGRATION_TEST(
diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index d02a60b7b2..88859819e0 100755
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -33,9 +33,18 @@
#include "llhttpclient.h"
#include "llsd.h"
#include "llsdserialize.h"
-
+#include "httpresponse.h"
+#include "llhttpsdhandler.h"
#include <boost/tokenizer.hpp>
+#include "httpcommon.h"
+#include "httprequest.h"
+#include "httpheaders.h"
+#include "httpoptions.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
+#include "llcorehttputil.h"
+
#include <map>
#include <set>
@@ -90,6 +99,12 @@ namespace LLAvatarNameCache
// Time-to-live for a temp cache entry.
const F64 TEMP_CACHE_ENTRY_LIFETIME = 60.0;
+ LLCore::HttpRequest::ptr_t sHttpRequest;
+ LLCore::HttpHeaders::ptr_t sHttpHeaders;
+ LLCore::HttpOptions::ptr_t sHttpOptions;
+ LLCore::HttpRequest::policy_t sHttpPolicy;
+ LLCore::HttpRequest::priority_t sHttpPriority;
+
//-----------------------------------------------------------------------
// Internal methods
//-----------------------------------------------------------------------
@@ -121,7 +136,13 @@ namespace LLAvatarNameCache
// Erase expired names from cache
void eraseUnrefreshed();
- bool expirationFromCacheControl(const LLSD& headers, F64 *expires);
+ //bool expirationFromCacheControl(LLCore::HttpHeaders *headers, F64 *expires);
+ bool expirationFromCacheControl(const LLSD& headers, F64 *expires);
+
+ // This is a coroutine. The only parameter that can be specified as a reference is the self
+ void requestAvatarNameCache_(LLCoros::self& self, std::string url, std::vector<LLUUID> agentIds);
+
+ void handleAvNameCacheSuccess(const LLSD &data, const LLSD &httpResult);
}
/* Sample response:
@@ -163,94 +184,125 @@ namespace LLAvatarNameCache
</llsd>
*/
-class LLAvatarNameResponder : public LLHTTPClient::Responder
+// Coroutine for sending and processing avatar name cache requests.
+// Do not call directly. See documentation in lleventcoro.h and llcoro.h for
+// further explanation.
+void LLAvatarNameCache::requestAvatarNameCache_(LLCoros::self& self, std::string url, std::vector<LLUUID> agentIds)
{
- 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;
-
-public:
- LLAvatarNameResponder(const std::vector<LLUUID>& agent_ids)
- : mAgentIDs(agent_ids)
- { }
-
-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(getResponseHeaders());
- F64 now = LLFrameTimer::getTotalSeconds();
+ LLEventStream replyPump("NameCacheReply", true);
+ LLCoreHttpUtil::HttpCoroHandler::ptr_t httpHandler =
+ LLCoreHttpUtil::HttpCoroHandler::ptr_t(new LLCoreHttpUtil::HttpCoroHandler(replyPump));
- const LLSD& agents = content["agents"];
- LLSD::array_const_iterator it = agents.beginArray();
- for ( ; it != agents.endArray(); ++it)
- {
- const LLSD& row = *it;
- LLUUID agent_id = row["id"].asUUID();
+ LL_DEBUGS("AvNameCache") << "Entering coroutine " << LLCoros::instance().getName(self)
+ << " with url '" << url << "', requesting " << agentIds.size() << " Agent Ids" << LL_ENDL;
- LLAvatarName av_name;
- av_name.fromLLSD(row);
+ try
+ {
+ bool success = true;
- // Use expiration time from header
- av_name.mExpires = expires;
+ LLAvatarNameCache::sHttpRequest->requestGet(
+ LLAvatarNameCache::sHttpPolicy, LLAvatarNameCache::sHttpPriority,
+ url, LLAvatarNameCache::sHttpOptions.get(),
+ LLAvatarNameCache::sHttpHeaders.get(), httpHandler.get());
- LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result for " << agent_id << LL_ENDL;
- av_name.dump();
-
- // cache it and fire signals
- LLAvatarNameCache::processName(agent_id, av_name);
- }
+ LLSD results = waitForEventOn(self, replyPump);
+ LLSD httpResults;
- // Same logic as error response case
- const LLSD& unresolved_agents = content["bad_ids"];
- S32 num_unresolved = unresolved_agents.size();
- if (num_unresolved > 0)
- {
- LL_WARNS("AvNameCache") << "LLAvatarNameResponder::result " << num_unresolved << " unresolved ids; "
- << "expires in " << expires - now << " seconds"
- << LL_ENDL;
- it = unresolved_agents.beginArray();
- for ( ; it != unresolved_agents.endArray(); ++it)
- {
- const LLUUID& agent_id = *it;
+ LL_DEBUGS() << results << LL_ENDL;
- LL_WARNS("AvNameCache") << "LLAvatarNameResponder::result "
- << "failed id " << agent_id
- << LL_ENDL;
+ if (!results.isMap())
+ {
+ LL_WARNS("AvNameCache") << " Invalid result returned from LLCoreHttpUtil::HttpCoroHandler." << LL_ENDL;
+ success = false;
+ }
+ else
+ {
+ httpResults = results["http_result"];
+ success = httpResults["success"].asBoolean();
+ if (!success)
+ {
+ LL_WARNS("AvNameCache") << "Error result from LLCoreHttpUtil::HttpCoroHandler. Code "
+ << httpResults["status"] << ": '" << httpResults["message"] << "'" << LL_ENDL;
+ }
+ }
+ if (!success)
+ { // on any sort of failure add dummy records for any agent IDs
+ // in this request that we do not have cached already
+ std::vector<LLUUID>::const_iterator it = agentIds.begin();
+ for ( ; it != agentIds.end(); ++it)
+ {
+ const LLUUID& agent_id = *it;
LLAvatarNameCache::handleAgentError(agent_id);
- }
- }
- LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result "
- << LLAvatarNameCache::sCache.size() << " cached names"
- << LL_ENDL;
+ }
+ return;
+ }
+
+ LLAvatarNameCache::handleAvNameCacheSuccess(results, httpResults);
+
}
+ catch (std::exception e)
+ {
+ LL_WARNS() << "Caught exception '" << e.what() << "'" << LL_ENDL;
+ }
+ catch (...)
+ {
+ LL_WARNS() << "Caught unknown exception." << LL_ENDL;
+ }
+}
- /*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") << 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();
- for ( ; it != mAgentIDs.end(); ++it)
- {
- const LLUUID& agent_id = *it;
- LLAvatarNameCache::handleAgentError(agent_id);
- }
- }
-};
+void LLAvatarNameCache::handleAvNameCacheSuccess(const LLSD &data, const LLSD &httpResult)
+{
+
+ LLSD headers = httpResult["headers"];
+ // Pull expiration out of headers if available
+ F64 expires = LLAvatarNameCache::nameExpirationFromHeaders(headers);
+ F64 now = LLFrameTimer::getTotalSeconds();
+
+ const LLSD& agents = data["agents"];
+ LLSD::array_const_iterator it = agents.beginArray();
+ for (; it != agents.endArray(); ++it)
+ {
+ const LLSD& row = *it;
+ LLUUID agent_id = row["id"].asUUID();
+
+ LLAvatarName av_name;
+ av_name.fromLLSD(row);
+
+ // Use expiration time from header
+ av_name.mExpires = expires;
+
+ LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result for " << agent_id << LL_ENDL;
+ av_name.dump();
+
+ // cache it and fire signals
+ LLAvatarNameCache::processName(agent_id, av_name);
+ }
+
+ // Same logic as error response case
+ const LLSD& unresolved_agents = data["bad_ids"];
+ S32 num_unresolved = unresolved_agents.size();
+ if (num_unresolved > 0)
+ {
+ LL_WARNS("AvNameCache") << "LLAvatarNameResponder::result " << num_unresolved << " unresolved ids; "
+ << "expires in " << expires - now << " seconds"
+ << LL_ENDL;
+ it = unresolved_agents.beginArray();
+ for (; it != unresolved_agents.endArray(); ++it)
+ {
+ const LLUUID& agent_id = *it;
+
+ LL_WARNS("AvNameCache") << "LLAvatarNameResponder::result "
+ << "failed id " << agent_id
+ << LL_ENDL;
+
+ LLAvatarNameCache::handleAgentError(agent_id);
+ }
+ }
+ LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result "
+ << LLAvatarNameCache::sCache.size() << " cached names"
+ << LL_ENDL;
+}
// Provide some fallback for agents that return errors
void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)
@@ -353,12 +405,17 @@ void LLAvatarNameCache::requestNamesViaCapability()
}
}
- if (!url.empty())
- {
- LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability requested "
- << ids << " ids"
- << LL_ENDL;
- LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids));
+ if (!url.empty())
+ {
+ LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability requested "
+ << ids << " ids"
+ << LL_ENDL;
+
+ std::string coroname =
+ LLCoros::instance().launch("LLAvatarNameCache::requestAvatarNameCache_",
+ boost::bind(&LLAvatarNameCache::requestAvatarNameCache_, _1, url, agent_ids));
+ LL_DEBUGS("AvNameCache") << coroname << " with url '" << url << "', agent_ids.size()=" << agent_ids.size() << LL_ENDL;
+
}
}
@@ -422,11 +479,20 @@ void LLAvatarNameCache::initClass(bool running, bool usePeopleAPI)
{
sRunning = running;
sUsePeopleAPI = usePeopleAPI;
+
+ sHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest());
+ sHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders(), false);
+ sHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false);
+ sHttpPolicy = LLCore::HttpRequest::DEFAULT_POLICY_ID;
+ sHttpPriority = 0;
}
void LLAvatarNameCache::cleanupClass()
{
- sCache.clear();
+ sHttpRequest.reset();
+ sHttpHeaders.reset();
+ sHttpOptions.reset();
+ sCache.clear();
}
void LLAvatarNameCache::importFile(std::istream& istr)
@@ -498,6 +564,8 @@ void LLAvatarNameCache::idle()
// By convention, start running at first idle() call
sRunning = true;
+ sHttpRequest->update(0L);
+
// *TODO: Possibly re-enabled this based on People API load measurements
// 100 ms is the threshold for "user speed" operations, so we can
// stall for about that long to batch up requests.
@@ -697,6 +765,50 @@ void LLAvatarNameCache::insert(const LLUUID& agent_id, const LLAvatarName& av_na
sCache[agent_id] = av_name;
}
+#if 0
+F64 LLAvatarNameCache::nameExpirationFromHeaders(LLCore::HttpHeaders *headers)
+{
+ F64 expires = 0.0;
+ if (expirationFromCacheControl(headers, &expires))
+ {
+ return expires;
+ }
+ else
+ {
+ // With no expiration info, default to an hour
+ const F64 DEFAULT_EXPIRES = 60.0 * 60.0;
+ F64 now = LLFrameTimer::getTotalSeconds();
+ return now + DEFAULT_EXPIRES;
+ }
+}
+
+bool LLAvatarNameCache::expirationFromCacheControl(LLCore::HttpHeaders *headers, F64 *expires)
+{
+ bool fromCacheControl = false;
+ F64 now = LLFrameTimer::getTotalSeconds();
+
+ // Allow the header to override the default
+ const std::string *cache_control;
+
+ cache_control = headers->find(HTTP_IN_HEADER_CACHE_CONTROL);
+
+ if (cache_control && !cache_control->empty())
+ {
+ S32 max_age = 0;
+ if (max_age_from_cache_control(*cache_control, &max_age))
+ {
+ *expires = now + (F64)max_age;
+ fromCacheControl = true;
+ }
+ }
+ LL_DEBUGS("AvNameCache")
+ << ( fromCacheControl ? "expires based on cache control " : "default expiration " )
+ << "in " << *expires - now << " seconds"
+ << LL_ENDL;
+
+ return fromCacheControl;
+}
+#else
F64 LLAvatarNameCache::nameExpirationFromHeaders(const LLSD& headers)
{
F64 expires = 0.0;
@@ -741,7 +853,7 @@ bool LLAvatarNameCache::expirationFromCacheControl(const LLSD& headers, F64 *exp
return fromCacheControl;
}
-
+#endif
void LLAvatarNameCache::addUseDisplayNamesCallback(const use_display_name_signal_t::slot_type& cb)
{
diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h
index ea016b3125..17b948f799 100755
--- a/indra/llmessage/llavatarnamecache.h
+++ b/indra/llmessage/llavatarnamecache.h
@@ -29,7 +29,6 @@
#define LLAVATARNAMECACHE_H
#include "llavatarname.h" // for convenience
-
#include <boost/signals2.hpp>
class LLSD;
@@ -49,7 +48,7 @@ namespace LLAvatarNameCache
void importFile(std::istream& istr);
void exportFile(std::ostream& ostr);
- // On the viewer, usually a simulator capabilitity.
+ // On the viewer, usually a simulator capabilities.
// If empty, name cache will fall back to using legacy name lookup system.
void setNameLookupURL(const std::string& name_lookup_url);
@@ -90,7 +89,7 @@ namespace LLAvatarNameCache
// Compute name expiration time from HTTP Cache-Control header,
// or return default value, in seconds from epoch.
- F64 nameExpirationFromHeaders(const LLSD& headers);
+ F64 nameExpirationFromHeaders(const LLSD& headers);
void addUseDisplayNamesCallback(const use_display_name_signal_t::slot_type& cb);
}
diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp
index ee80b0fd94..30f5f3d3ed 100644
--- a/indra/llmessage/llcorehttputil.cpp
+++ b/indra/llmessage/llcorehttputil.cpp
@@ -30,15 +30,17 @@
#include <sstream>
#include "llcorehttputil.h"
+#include "llhttpconstants.h"
#include "llsdserialize.h"
-
using namespace LLCore;
namespace LLCoreHttpUtil
{
+
+
// *TODO: Currently converts only from XML content. A mode
// to convert using fromBinary() might be useful as well. Mesh
// headers could use it.
@@ -88,6 +90,57 @@ HttpHandle requestPostWithLLSD(HttpRequest * request,
return handle;
}
+HttpHandle requestPostWithLLSD(HttpRequest::ptr_t & request,
+ HttpRequest::policy_t policy_id,
+ HttpRequest::priority_t priority,
+ const std::string & url,
+ const LLSD & body,
+ HttpOptions::ptr_t & options,
+ HttpHeaders::ptr_t & headers,
+ HttpHandler * handler)
+{
+ return requestPostWithLLSD(request.get(), policy_id, priority,
+ url, body, options.get(), headers.get(), handler);
+}
+
+HttpHandle requestPutWithLLSD(HttpRequest * request,
+ HttpRequest::policy_t policy_id,
+ HttpRequest::priority_t priority,
+ const std::string & url,
+ const LLSD & body,
+ HttpOptions * options,
+ HttpHeaders * headers,
+ HttpHandler * handler)
+{
+ HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
+
+ BufferArray * ba = new BufferArray();
+ BufferArrayStream bas(ba);
+ LLSDSerialize::toXML(body, bas);
+
+ handle = request->requestPut(policy_id,
+ priority,
+ url,
+ ba,
+ options,
+ headers,
+ handler);
+ ba->release();
+ return handle;
+}
+
+HttpHandle requestPutWithLLSD(HttpRequest::ptr_t & request,
+ HttpRequest::policy_t policy_id,
+ HttpRequest::priority_t priority,
+ const std::string & url,
+ const LLSD & body,
+ HttpOptions::ptr_t & options,
+ HttpHeaders::ptr_t & headers,
+ HttpHandler * handler)
+{
+ return requestPutWithLLSD(request.get(), policy_id, priority,
+ url, body, options.get(), headers.get(), handler);
+}
std::string responseToString(LLCore::HttpResponse * response)
{
@@ -135,5 +188,118 @@ std::string responseToString(LLCore::HttpResponse * response)
}
+HttpCoroHandler::HttpCoroHandler(LLEventStream &reply) :
+ mReplyPump(reply)
+{
+}
+
+void HttpCoroHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response)
+{
+ LLSD result;
+
+ LLCore::HttpStatus status = response->getStatus();
+
+ if (!status)
+ {
+ result = LLSD::emptyMap();
+ LL_WARNS()
+ << "\n--------------------------------------------------------------------------\n"
+ << " Error[" << status.toULong() << "] cannot access url '" << response->getRequestURL()
+ << "' because " << status.toString()
+ << "\n--------------------------------------------------------------------------"
+ << LL_ENDL;
+
+ }
+ else
+ {
+ const bool emit_parse_errors = false;
+
+ bool parsed = !((response->getBodySize() == 0) ||
+ !LLCoreHttpUtil::responseToLLSD(response, emit_parse_errors, result));
+
+ if (!parsed)
+ {
+ // Only emit a warning if we failed to parse when 'content-type' == 'application/llsd+xml'
+ LLCore::HttpHeaders::ptr_t headers(response->getHeaders());
+ const std::string *contentType = (headers) ? headers->find(HTTP_IN_HEADER_CONTENT_TYPE) : NULL;
+
+ if (contentType && (HTTP_CONTENT_LLSD_XML == *contentType))
+ {
+ std::string thebody = LLCoreHttpUtil::responseToString(response);
+ LL_WARNS() << "Failed to deserialize . " << response->getRequestURL() << " [status:" << response->getStatus().toString() << "] "
+ << " body: " << thebody << LL_ENDL;
+
+ // Replace the status with a new one indicating the failure.
+ status = LLCore::HttpStatus(499, "Failed to deserialize LLSD.");
+ }
+ }
+
+ if (result.isUndefined())
+ {
+ // If we've gotten to this point and the result LLSD is still undefined
+ // either there was an issue deserializing the body or the response was
+ // blank. Create an empty map to hold the result either way.
+ result = LLSD::emptyMap();
+ }
+ }
+
+ buildStatusEntry(response, status, result);
+ mReplyPump.post(result);
+}
+
+void HttpCoroHandler::buildStatusEntry(LLCore::HttpResponse *response, LLCore::HttpStatus status, LLSD &result)
+{
+ LLSD httpresults = LLSD::emptyMap();
+
+ httpresults["success"] = static_cast<LLSD::Boolean>(status);
+ httpresults["type"] = static_cast<LLSD::Integer>(status.getType());
+ httpresults["status"] = static_cast<LLSD::Integer>(status.getStatus());
+ httpresults["message"] = static_cast<LLSD::String>(status.getMessage());
+ httpresults["url"] = static_cast<LLSD::String>(response->getRequestURL());
+
+ LLSD httpHeaders = LLSD::emptyMap();
+ LLCore::HttpHeaders * hdrs = response->getHeaders();
+
+ if (hdrs)
+ {
+ for (LLCore::HttpHeaders::iterator it = hdrs->begin(); it != hdrs->end(); ++it)
+ {
+ if (!(*it).second.empty())
+ {
+ httpHeaders[(*it).first] = (*it).second;
+ }
+ else
+ {
+ httpHeaders[(*it).first] = static_cast<LLSD::Boolean>(true);
+ }
+ }
+ }
+
+ httpresults["headers"] = httpHeaders;
+ result["http_result"] = httpresults;
+}
+
+HttpRequestPumper::HttpRequestPumper(const LLCore::HttpRequest::ptr_t &request):
+ mHttpRequest(request)
+{
+ mBoundListener = LLEventPumps::instance().obtain("mainloop").
+ listen(LLEventPump::inventName(), boost::bind(&HttpRequestPumper::pollRequest, this, _1));
+}
+
+HttpRequestPumper::~HttpRequestPumper()
+{
+ if (mBoundListener.connected())
+ {
+ mBoundListener.disconnect();
+ }
+}
+
+bool HttpRequestPumper::pollRequest(const LLSD&)
+{
+ mHttpRequest->update(0L);
+ return false;
+}
+
+
} // end namespace LLCoreHttpUtil
diff --git a/indra/llmessage/llcorehttputil.h b/indra/llmessage/llcorehttputil.h
index d40172bc7a..4ae6e112b3 100644
--- a/indra/llmessage/llcorehttputil.h
+++ b/indra/llmessage/llcorehttputil.h
@@ -39,6 +39,7 @@
#include "bufferarray.h"
#include "bufferstream.h"
#include "llsd.h"
+#include "llevents.h"
///
/// The base llcorehttp library implements many HTTP idioms
@@ -109,6 +110,92 @@ LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest * request,
LLCore::HttpHeaders * headers,
LLCore::HttpHandler * handler);
+LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest::ptr_t & request,
+ LLCore::HttpRequest::policy_t policy_id,
+ LLCore::HttpRequest::priority_t priority,
+ const std::string & url,
+ const LLSD & body,
+ LLCore::HttpOptions::ptr_t & options,
+ LLCore::HttpHeaders::ptr_t & headers,
+ LLCore::HttpHandler * handler);
+
+/// Issue a standard HttpRequest::requestPut() call but using
+/// and LLSD object as the request body. Conventions are the
+/// same as with that method. Caller is expected to provide
+/// an HttpHeaders object with a correct 'Content-Type:' header.
+/// One will not be provided by this call.
+///
+/// @return If request is successfully issued, the
+/// HttpHandle representing the request.
+/// On error, LLCORE_HTTP_HANDLE_INVALID
+/// is returned and caller can fetch detailed
+/// status with the getStatus() method on the
+/// request object. In case of error, no
+/// request is queued and caller may need to
+/// perform additional cleanup such as freeing
+/// a now-useless HttpHandler object.
+///
+LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest * request,
+ LLCore::HttpRequest::policy_t policy_id,
+ LLCore::HttpRequest::priority_t priority,
+ const std::string & url,
+ const LLSD & body,
+ LLCore::HttpOptions * options,
+ LLCore::HttpHeaders * headers,
+ LLCore::HttpHandler * handler);
+
+LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & request,
+ LLCore::HttpRequest::policy_t policy_id,
+ LLCore::HttpRequest::priority_t priority,
+ const std::string & url,
+ const LLSD & body,
+ LLCore::HttpOptions::ptr_t & options,
+ LLCore::HttpHeaders::ptr_t & headers,
+ LLCore::HttpHandler * handler);
+
+/// The HttpCoroHandler is a specialization of the LLCore::HttpHandler for
+/// interacting with coroutines. When the request is completed the response
+/// will be posted onto the supplied Event Pump.
+///
+/// The LLSD posted back to the coroutine will have the following additions:
+/// llsd["http_result"] -+- ["message"] - An error message returned from the HTTP status
+/// +- ["status"] - The status code associated with the HTTP call
+/// +- ["success"] - Success of failure of the HTTP call and LLSD parsing.
+/// +- ["type"] - The LLCore::HttpStatus type associted with the HTTP call
+/// +- ["url"] - The URL used to make the call.
+/// +- ["headers"] - A map of name name value pairs with the HTTP headers.
+///
+class HttpCoroHandler : public LLCore::HttpHandler
+{
+public:
+ HttpCoroHandler(LLEventStream &reply);
+
+ virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response);
+
+ typedef boost::shared_ptr<HttpCoroHandler> ptr_t;
+
+private:
+ void buildStatusEntry(LLCore::HttpResponse *response, LLCore::HttpStatus status, LLSD &result);
+
+ LLEventStream &mReplyPump;
+};
+
+/// The HttpRequestPumper is a utility class. When constructed it will poll the
+/// supplied HttpRequest once per frame until it is destroyed.
+///
+class HttpRequestPumper
+{
+public:
+ HttpRequestPumper(const LLCore::HttpRequest::ptr_t &request);
+ ~HttpRequestPumper();
+
+private:
+ bool pollRequest(const LLSD&);
+
+ LLTempBoundListener mBoundListener;
+ LLCore::HttpRequest::ptr_t mHttpRequest;
+};
+
} // end namespace LLCoreHttpUtil
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index 73df47b933..ef28a4d211 100755
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -69,13 +69,15 @@
do this.
*/
+// *TODO: TSN remove the commented code from this file
//////////////////////////////////////////////////////////////////////////////
static const U32 EASY_HANDLE_POOL_SIZE = 5;
static const S32 MULTI_PERFORM_CALL_REPEAT = 5;
static const S32 CURL_REQUEST_TIMEOUT = 120; // seconds per operation
static const S32 CURL_CONNECT_TIMEOUT = 30; //seconds to wait for a connection
-static const S32 MAX_ACTIVE_REQUEST_COUNT = 100;
+
+//static const S32 MAX_ACTIVE_REQUEST_COUNT = 100;
// DEBUG //
S32 gCurlEasyCount = 0;
@@ -676,6 +678,7 @@ void LLCurl::Easy::prepRequest(const std::string& url,
}
////////////////////////////////////////////////////////////////////////////
+#if 1
LLCurl::Multi::Multi(F32 idle_time_out)
: mQueued(0),
mErrorCount(0),
@@ -1056,6 +1059,7 @@ void LLCurl::Multi::removeEasy(Easy* easy)
easyFree(easy);
}
+#endif
//------------------------------------------------------------
//LLCurlThread
LLCurlThread::CurlRequest::CurlRequest(handle_t handle, LLCurl::Multi* multi, LLCurlThread* curl_thread) :
@@ -1176,428 +1180,428 @@ std::string LLCurl::strerror(CURLcode errorcode)
// For generating a simple request for data
// using one multi and one easy per request
-LLCurlRequest::LLCurlRequest() :
- mActiveMulti(NULL),
- mActiveRequestCount(0)
-{
- mProcessing = FALSE;
-}
-
-LLCurlRequest::~LLCurlRequest()
-{
- //stop all Multi handle background threads
- for (curlmulti_set_t::iterator iter = mMultiSet.begin(); iter != mMultiSet.end(); ++iter)
- {
- LLCurl::getCurlThread()->killMulti(*iter) ;
- }
- mMultiSet.clear() ;
-}
-
-void LLCurlRequest::addMulti()
-{
- LLCurl::Multi* multi = new LLCurl::Multi();
- if(!multi->isValid())
- {
- LLCurl::getCurlThread()->killMulti(multi) ;
- mActiveMulti = NULL ;
- mActiveRequestCount = 0 ;
- return;
- }
-
- mMultiSet.insert(multi);
- mActiveMulti = multi;
- mActiveRequestCount = 0;
-}
-
-LLCurl::Easy* LLCurlRequest::allocEasy()
-{
- if (!mActiveMulti ||
- mActiveRequestCount >= MAX_ACTIVE_REQUEST_COUNT ||
- mActiveMulti->mErrorCount > 0)
- {
- addMulti();
- }
- if(!mActiveMulti)
- {
- return NULL ;
- }
-
- //llassert_always(mActiveMulti);
- ++mActiveRequestCount;
- LLCurl::Easy* easy = mActiveMulti->allocEasy();
- return easy;
-}
-
-bool LLCurlRequest::addEasy(LLCurl::Easy* easy)
-{
- llassert_always(mActiveMulti);
-
- if (mProcessing)
- {
- LL_ERRS() << "Posting to a LLCurlRequest instance from within a responder is not allowed (causes DNS timeouts)." << LL_ENDL;
- }
- bool res = mActiveMulti->addEasy(easy);
- return res;
-}
-
-void LLCurlRequest::get(const std::string& url, LLCurl::ResponderPtr responder)
-{
- getByteRange(url, headers_t(), 0, -1, responder);
-}
-
-// Note: (length==0) is interpreted as "the rest of the file", i.e. the whole file if (offset==0) or
-// the remainder of the file if not.
-bool LLCurlRequest::getByteRange(const std::string& url,
- const headers_t& headers,
- S32 offset, S32 length,
- LLCurl::ResponderPtr responder)
-{
- llassert(LLCurl::sNotQuitting);
- LLCurl::Easy* easy = allocEasy();
- if (!easy)
- {
- return false;
- }
- easy->prepRequest(url, headers, responder);
- easy->setopt(CURLOPT_HTTPGET, 1);
- if (length > 0)
- {
- std::string range = llformat("bytes=%d-%d", offset,offset+length-1);
- easy->slist_append(HTTP_OUT_HEADER_RANGE, range);
- }
- else if (offset > 0)
- {
- std::string range = llformat("bytes=%d-", offset);
- easy->slist_append(HTTP_OUT_HEADER_RANGE, range);
- }
- easy->setHeaders();
- bool res = addEasy(easy);
- return res;
-}
-
-bool LLCurlRequest::post(const std::string& url,
- const headers_t& headers,
- const LLSD& data,
- LLCurl::ResponderPtr responder, S32 time_out)
-{
- llassert(LLCurl::sNotQuitting);
- LLCurl::Easy* easy = allocEasy();
- if (!easy)
- {
- return false;
- }
- easy->prepRequest(url, headers, responder, time_out);
-
- LLSDSerialize::toXML(data, easy->getInput());
- S32 bytes = easy->getInput().str().length();
-
- easy->setopt(CURLOPT_POST, 1);
- easy->setopt(CURLOPT_POSTFIELDS, (void*)NULL);
- easy->setopt(CURLOPT_POSTFIELDSIZE, bytes);
-
- easy->slist_append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML);
- easy->setHeaders();
-
- LL_DEBUGS() << "POSTING: " << bytes << " bytes." << LL_ENDL;
- bool res = addEasy(easy);
- return res;
-}
-
-bool LLCurlRequest::post(const std::string& url,
- const headers_t& headers,
- const std::string& data,
- LLCurl::ResponderPtr responder, S32 time_out)
-{
- llassert(LLCurl::sNotQuitting);
- LLCurl::Easy* easy = allocEasy();
- if (!easy)
- {
- return false;
- }
- easy->prepRequest(url, headers, responder, time_out);
-
- easy->getInput().write(data.data(), data.size());
- S32 bytes = easy->getInput().str().length();
-
- easy->setopt(CURLOPT_POST, 1);
- easy->setopt(CURLOPT_POSTFIELDS, (void*)NULL);
- easy->setopt(CURLOPT_POSTFIELDSIZE, bytes);
-
- easy->slist_append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_OCTET_STREAM);
- easy->setHeaders();
-
- LL_DEBUGS() << "POSTING: " << bytes << " bytes." << LL_ENDL;
- bool res = addEasy(easy);
- return res;
-}
-
-// Note: call once per frame
-S32 LLCurlRequest::process()
-{
- S32 res = 0;
-
- mProcessing = TRUE;
- for (curlmulti_set_t::iterator iter = mMultiSet.begin();
- iter != mMultiSet.end(); )
- {
- curlmulti_set_t::iterator curiter = iter++;
- LLCurl::Multi* multi = *curiter;
-
- if(!multi->isValid())
- {
- if(multi == mActiveMulti)
- {
- mActiveMulti = NULL ;
- mActiveRequestCount = 0 ;
- }
- mMultiSet.erase(curiter) ;
- LLCurl::getCurlThread()->killMulti(multi) ;
- continue ;
- }
-
- S32 tres = multi->process();
- res += tres;
- if (multi != mActiveMulti && tres == 0 && multi->mQueued == 0)
- {
- mMultiSet.erase(curiter);
- LLCurl::getCurlThread()->killMulti(multi);
- }
- }
- mProcessing = FALSE;
- return res;
-}
-
-S32 LLCurlRequest::getQueued()
-{
- S32 queued = 0;
- for (curlmulti_set_t::iterator iter = mMultiSet.begin();
- iter != mMultiSet.end(); )
- {
- curlmulti_set_t::iterator curiter = iter++;
- LLCurl::Multi* multi = *curiter;
-
- if(!multi->isValid())
- {
- if(multi == mActiveMulti)
- {
- mActiveMulti = NULL ;
- mActiveRequestCount = 0 ;
- }
- LLCurl::getCurlThread()->killMulti(multi);
- mMultiSet.erase(curiter) ;
- continue ;
- }
-
- queued += multi->mQueued;
- if (multi->getState() != LLCurl::Multi::STATE_READY)
- {
- ++queued;
- }
- }
- return queued;
-}
-
-LLCurlTextureRequest::LLCurlTextureRequest(S32 concurrency) :
- LLCurlRequest(),
- mConcurrency(concurrency),
- mInQueue(0),
- mMutex(NULL),
- mHandleCounter(1),
- mTotalIssuedRequests(0),
- mTotalReceivedBits(0)
-{
- mGlobalTimer.reset();
-}
-
-LLCurlTextureRequest::~LLCurlTextureRequest()
-{
- mRequestMap.clear();
-
- for(req_queue_t::iterator iter = mCachedRequests.begin(); iter != mCachedRequests.end(); ++iter)
- {
- delete *iter;
- }
- mCachedRequests.clear();
-}
-
-//return 0: success
-// > 0: cached handle
-U32 LLCurlTextureRequest::getByteRange(const std::string& url,
- const headers_t& headers,
- S32 offset, S32 length, U32 pri,
- LLCurl::ResponderPtr responder, F32 delay_time)
-{
- U32 ret_val = 0;
- bool success = false;
-
- if(mInQueue < mConcurrency && delay_time < 0.f)
- {
- success = LLCurlRequest::getByteRange(url, headers, offset, length, responder);
- }
-
- LLMutexLock lock(&mMutex);
-
- if(success)
- {
- mInQueue++;
- mTotalIssuedRequests++;
- }
- else
- {
- request_t* request = new request_t(mHandleCounter, url, headers, offset, length, pri, responder);
- if(delay_time > 0.f)
- {
- request->mStartTime = mGlobalTimer.getElapsedTimeF32() + delay_time;
- }
-
- mCachedRequests.insert(request);
- mRequestMap[mHandleCounter] = request;
- ret_val = mHandleCounter;
- mHandleCounter++;
-
- if(!mHandleCounter)
- {
- mHandleCounter = 1;
- }
- }
-
- return ret_val;
-}
-
-void LLCurlTextureRequest::completeRequest(S32 received_bytes)
-{
- LLMutexLock lock(&mMutex);
-
- llassert_always(mInQueue > 0);
-
- mInQueue--;
- mTotalReceivedBits += received_bytes * 8;
-}
-
-void LLCurlTextureRequest::nextRequests()
-{
- if(mCachedRequests.empty() || mInQueue >= mConcurrency)
- {
- return;
- }
-
- F32 cur_time = mGlobalTimer.getElapsedTimeF32();
-
- req_queue_t::iterator iter;
- {
- LLMutexLock lock(&mMutex);
- iter = mCachedRequests.begin();
- }
- while(1)
- {
- request_t* request = *iter;
- if(request->mStartTime < cur_time)
- {
- if(!LLCurlRequest::getByteRange(request->mUrl, request->mHeaders, request->mOffset, request->mLength, request->mResponder))
- {
- break;
- }
-
- LLMutexLock lock(&mMutex);
- ++iter;
- mInQueue++;
- mTotalIssuedRequests++;
- mCachedRequests.erase(request);
- mRequestMap.erase(request->mHandle);
- delete request;
-
- if(iter == mCachedRequests.end() || mInQueue >= mConcurrency)
- {
- break;
- }
- }
- else
- {
- LLMutexLock lock(&mMutex);
- ++iter;
- if(iter == mCachedRequests.end() || mInQueue >= mConcurrency)
- {
- break;
- }
- }
- }
-
- return;
-}
-
-void LLCurlTextureRequest::updatePriority(U32 handle, U32 pri)
-{
- if(!handle)
- {
- return;
- }
-
- LLMutexLock lock(&mMutex);
-
- std::map<S32, request_t*>::iterator iter = mRequestMap.find(handle);
- if(iter != mRequestMap.end())
- {
- request_t* req = iter->second;
-
- if(req->mPriority != pri)
- {
- mCachedRequests.erase(req);
- req->mPriority = pri;
- mCachedRequests.insert(req);
- }
- }
-}
-
-void LLCurlTextureRequest::removeRequest(U32 handle)
-{
- if(!handle)
- {
- return;
- }
-
- LLMutexLock lock(&mMutex);
-
- std::map<S32, request_t*>::iterator iter = mRequestMap.find(handle);
- if(iter != mRequestMap.end())
- {
- request_t* req = iter->second;
- mRequestMap.erase(iter);
- mCachedRequests.erase(req);
- delete req;
- }
-}
-
-bool LLCurlTextureRequest::isWaiting(U32 handle)
-{
- if(!handle)
- {
- return false;
- }
-
- LLMutexLock lock(&mMutex);
- return mRequestMap.find(handle) != mRequestMap.end();
-}
-
-U32 LLCurlTextureRequest::getTotalReceivedBits()
-{
- LLMutexLock lock(&mMutex);
-
- U32 bits = mTotalReceivedBits;
- mTotalReceivedBits = 0;
- return bits;
-}
-
-U32 LLCurlTextureRequest::getTotalIssuedRequests()
-{
- LLMutexLock lock(&mMutex);
- return mTotalIssuedRequests;
-}
-
-S32 LLCurlTextureRequest::getNumRequests()
-{
- LLMutexLock lock(&mMutex);
- return mInQueue;
-}
+// LLCurlRequest::LLCurlRequest() :
+// mActiveMulti(NULL),
+// mActiveRequestCount(0)
+// {
+// mProcessing = FALSE;
+// }
+//
+// LLCurlRequest::~LLCurlRequest()
+// {
+// //stop all Multi handle background threads
+// for (curlmulti_set_t::iterator iter = mMultiSet.begin(); iter != mMultiSet.end(); ++iter)
+// {
+// LLCurl::getCurlThread()->killMulti(*iter) ;
+// }
+// mMultiSet.clear() ;
+// }
+//
+// void LLCurlRequest::addMulti()
+// {
+// LLCurl::Multi* multi = new LLCurl::Multi();
+// if(!multi->isValid())
+// {
+// LLCurl::getCurlThread()->killMulti(multi) ;
+// mActiveMulti = NULL ;
+// mActiveRequestCount = 0 ;
+// return;
+// }
+//
+// mMultiSet.insert(multi);
+// mActiveMulti = multi;
+// mActiveRequestCount = 0;
+// }
+//
+// LLCurl::Easy* LLCurlRequest::allocEasy()
+// {
+// if (!mActiveMulti ||
+// mActiveRequestCount >= MAX_ACTIVE_REQUEST_COUNT ||
+// mActiveMulti->mErrorCount > 0)
+// {
+// addMulti();
+// }
+// if(!mActiveMulti)
+// {
+// return NULL ;
+// }
+//
+// //llassert_always(mActiveMulti);
+// ++mActiveRequestCount;
+// LLCurl::Easy* easy = mActiveMulti->allocEasy();
+// return easy;
+// }
+//
+// bool LLCurlRequest::addEasy(LLCurl::Easy* easy)
+// {
+// llassert_always(mActiveMulti);
+//
+// if (mProcessing)
+// {
+// LL_ERRS() << "Posting to a LLCurlRequest instance from within a responder is not allowed (causes DNS timeouts)." << LL_ENDL;
+// }
+// bool res = mActiveMulti->addEasy(easy);
+// return res;
+// }
+//
+// void LLCurlRequest::get(const std::string& url, LLCurl::ResponderPtr responder)
+// {
+// getByteRange(url, headers_t(), 0, -1, responder);
+// }
+//
+// // Note: (length==0) is interpreted as "the rest of the file", i.e. the whole file if (offset==0) or
+// // the remainder of the file if not.
+// bool LLCurlRequest::getByteRange(const std::string& url,
+// const headers_t& headers,
+// S32 offset, S32 length,
+// LLCurl::ResponderPtr responder)
+// {
+// llassert(LLCurl::sNotQuitting);
+// LLCurl::Easy* easy = allocEasy();
+// if (!easy)
+// {
+// return false;
+// }
+// easy->prepRequest(url, headers, responder);
+// easy->setopt(CURLOPT_HTTPGET, 1);
+// if (length > 0)
+// {
+// std::string range = llformat("bytes=%d-%d", offset,offset+length-1);
+// easy->slist_append(HTTP_OUT_HEADER_RANGE, range);
+// }
+// else if (offset > 0)
+// {
+// std::string range = llformat("bytes=%d-", offset);
+// easy->slist_append(HTTP_OUT_HEADER_RANGE, range);
+// }
+// easy->setHeaders();
+// bool res = addEasy(easy);
+// return res;
+// }
+//
+// bool LLCurlRequest::post(const std::string& url,
+// const headers_t& headers,
+// const LLSD& data,
+// LLCurl::ResponderPtr responder, S32 time_out)
+// {
+// llassert(LLCurl::sNotQuitting);
+// LLCurl::Easy* easy = allocEasy();
+// if (!easy)
+// {
+// return false;
+// }
+// easy->prepRequest(url, headers, responder, time_out);
+//
+// LLSDSerialize::toXML(data, easy->getInput());
+// S32 bytes = easy->getInput().str().length();
+//
+// easy->setopt(CURLOPT_POST, 1);
+// easy->setopt(CURLOPT_POSTFIELDS, (void*)NULL);
+// easy->setopt(CURLOPT_POSTFIELDSIZE, bytes);
+//
+// easy->slist_append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML);
+// easy->setHeaders();
+//
+// LL_DEBUGS() << "POSTING: " << bytes << " bytes." << LL_ENDL;
+// bool res = addEasy(easy);
+// return res;
+// }
+//
+// bool LLCurlRequest::post(const std::string& url,
+// const headers_t& headers,
+// const std::string& data,
+// LLCurl::ResponderPtr responder, S32 time_out)
+// {
+// llassert(LLCurl::sNotQuitting);
+// LLCurl::Easy* easy = allocEasy();
+// if (!easy)
+// {
+// return false;
+// }
+// easy->prepRequest(url, headers, responder, time_out);
+//
+// easy->getInput().write(data.data(), data.size());
+// S32 bytes = easy->getInput().str().length();
+//
+// easy->setopt(CURLOPT_POST, 1);
+// easy->setopt(CURLOPT_POSTFIELDS, (void*)NULL);
+// easy->setopt(CURLOPT_POSTFIELDSIZE, bytes);
+//
+// easy->slist_append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_OCTET_STREAM);
+// easy->setHeaders();
+//
+// LL_DEBUGS() << "POSTING: " << bytes << " bytes." << LL_ENDL;
+// bool res = addEasy(easy);
+// return res;
+// }
+//
+// // Note: call once per frame
+// S32 LLCurlRequest::process()
+// {
+// S32 res = 0;
+//
+// mProcessing = TRUE;
+// for (curlmulti_set_t::iterator iter = mMultiSet.begin();
+// iter != mMultiSet.end(); )
+// {
+// curlmulti_set_t::iterator curiter = iter++;
+// LLCurl::Multi* multi = *curiter;
+//
+// if(!multi->isValid())
+// {
+// if(multi == mActiveMulti)
+// {
+// mActiveMulti = NULL ;
+// mActiveRequestCount = 0 ;
+// }
+// mMultiSet.erase(curiter) ;
+// LLCurl::getCurlThread()->killMulti(multi) ;
+// continue ;
+// }
+//
+// S32 tres = multi->process();
+// res += tres;
+// if (multi != mActiveMulti && tres == 0 && multi->mQueued == 0)
+// {
+// mMultiSet.erase(curiter);
+// LLCurl::getCurlThread()->killMulti(multi);
+// }
+// }
+// mProcessing = FALSE;
+// return res;
+// }
+//
+// S32 LLCurlRequest::getQueued()
+// {
+// S32 queued = 0;
+// for (curlmulti_set_t::iterator iter = mMultiSet.begin();
+// iter != mMultiSet.end(); )
+// {
+// curlmulti_set_t::iterator curiter = iter++;
+// LLCurl::Multi* multi = *curiter;
+//
+// if(!multi->isValid())
+// {
+// if(multi == mActiveMulti)
+// {
+// mActiveMulti = NULL ;
+// mActiveRequestCount = 0 ;
+// }
+// LLCurl::getCurlThread()->killMulti(multi);
+// mMultiSet.erase(curiter) ;
+// continue ;
+// }
+//
+// queued += multi->mQueued;
+// if (multi->getState() != LLCurl::Multi::STATE_READY)
+// {
+// ++queued;
+// }
+// }
+// return queued;
+// }
+
+// LLCurlTextureRequest::LLCurlTextureRequest(S32 concurrency) :
+// LLCurlRequest(),
+// mConcurrency(concurrency),
+// mInQueue(0),
+// mMutex(NULL),
+// mHandleCounter(1),
+// mTotalIssuedRequests(0),
+// mTotalReceivedBits(0)
+// {
+// mGlobalTimer.reset();
+// }
+//
+// LLCurlTextureRequest::~LLCurlTextureRequest()
+// {
+// mRequestMap.clear();
+//
+// for(req_queue_t::iterator iter = mCachedRequests.begin(); iter != mCachedRequests.end(); ++iter)
+// {
+// delete *iter;
+// }
+// mCachedRequests.clear();
+// }
+//
+// //return 0: success
+// // > 0: cached handle
+// U32 LLCurlTextureRequest::getByteRange(const std::string& url,
+// const headers_t& headers,
+// S32 offset, S32 length, U32 pri,
+// LLCurl::ResponderPtr responder, F32 delay_time)
+// {
+// U32 ret_val = 0;
+// bool success = false;
+//
+// if(mInQueue < mConcurrency && delay_time < 0.f)
+// {
+// success = LLCurlRequest::getByteRange(url, headers, offset, length, responder);
+// }
+//
+// LLMutexLock lock(&mMutex);
+//
+// if(success)
+// {
+// mInQueue++;
+// mTotalIssuedRequests++;
+// }
+// else
+// {
+// request_t* request = new request_t(mHandleCounter, url, headers, offset, length, pri, responder);
+// if(delay_time > 0.f)
+// {
+// request->mStartTime = mGlobalTimer.getElapsedTimeF32() + delay_time;
+// }
+//
+// mCachedRequests.insert(request);
+// mRequestMap[mHandleCounter] = request;
+// ret_val = mHandleCounter;
+// mHandleCounter++;
+//
+// if(!mHandleCounter)
+// {
+// mHandleCounter = 1;
+// }
+// }
+//
+// return ret_val;
+// }
+//
+// void LLCurlTextureRequest::completeRequest(S32 received_bytes)
+// {
+// LLMutexLock lock(&mMutex);
+//
+// llassert_always(mInQueue > 0);
+//
+// mInQueue--;
+// mTotalReceivedBits += received_bytes * 8;
+// }
+//
+// void LLCurlTextureRequest::nextRequests()
+// {
+// if(mCachedRequests.empty() || mInQueue >= mConcurrency)
+// {
+// return;
+// }
+//
+// F32 cur_time = mGlobalTimer.getElapsedTimeF32();
+//
+// req_queue_t::iterator iter;
+// {
+// LLMutexLock lock(&mMutex);
+// iter = mCachedRequests.begin();
+// }
+// while(1)
+// {
+// request_t* request = *iter;
+// if(request->mStartTime < cur_time)
+// {
+// if(!LLCurlRequest::getByteRange(request->mUrl, request->mHeaders, request->mOffset, request->mLength, request->mResponder))
+// {
+// break;
+// }
+//
+// LLMutexLock lock(&mMutex);
+// ++iter;
+// mInQueue++;
+// mTotalIssuedRequests++;
+// mCachedRequests.erase(request);
+// mRequestMap.erase(request->mHandle);
+// delete request;
+//
+// if(iter == mCachedRequests.end() || mInQueue >= mConcurrency)
+// {
+// break;
+// }
+// }
+// else
+// {
+// LLMutexLock lock(&mMutex);
+// ++iter;
+// if(iter == mCachedRequests.end() || mInQueue >= mConcurrency)
+// {
+// break;
+// }
+// }
+// }
+//
+// return;
+// }
+//
+// void LLCurlTextureRequest::updatePriority(U32 handle, U32 pri)
+// {
+// if(!handle)
+// {
+// return;
+// }
+//
+// LLMutexLock lock(&mMutex);
+//
+// std::map<S32, request_t*>::iterator iter = mRequestMap.find(handle);
+// if(iter != mRequestMap.end())
+// {
+// request_t* req = iter->second;
+//
+// if(req->mPriority != pri)
+// {
+// mCachedRequests.erase(req);
+// req->mPriority = pri;
+// mCachedRequests.insert(req);
+// }
+// }
+// }
+//
+// void LLCurlTextureRequest::removeRequest(U32 handle)
+// {
+// if(!handle)
+// {
+// return;
+// }
+//
+// LLMutexLock lock(&mMutex);
+//
+// std::map<S32, request_t*>::iterator iter = mRequestMap.find(handle);
+// if(iter != mRequestMap.end())
+// {
+// request_t* req = iter->second;
+// mRequestMap.erase(iter);
+// mCachedRequests.erase(req);
+// delete req;
+// }
+// }
+//
+// bool LLCurlTextureRequest::isWaiting(U32 handle)
+// {
+// if(!handle)
+// {
+// return false;
+// }
+//
+// LLMutexLock lock(&mMutex);
+// return mRequestMap.find(handle) != mRequestMap.end();
+// }
+//
+// U32 LLCurlTextureRequest::getTotalReceivedBits()
+// {
+// LLMutexLock lock(&mMutex);
+//
+// U32 bits = mTotalReceivedBits;
+// mTotalReceivedBits = 0;
+// return bits;
+// }
+//
+// U32 LLCurlTextureRequest::getTotalIssuedRequests()
+// {
+// LLMutexLock lock(&mMutex);
+// return mTotalIssuedRequests;
+// }
+//
+// S32 LLCurlTextureRequest::getNumRequests()
+// {
+// LLMutexLock lock(&mMutex);
+// return mInQueue;
+// }
////////////////////////////////////////////////////////////////////////////
// For generating one easy request
@@ -1988,10 +1992,10 @@ void LLCurlFF::check_easy_code(CURLcode code)
{
check_curl_code(code);
}
-void LLCurlFF::check_multi_code(CURLMcode code)
-{
- check_curl_multi_code(code);
-}
+// void LLCurlFF::check_multi_code(CURLMcode code)
+// {
+// check_curl_multi_code(code);
+// }
// Static
diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h
index 385d9fffa8..06b3ce45e1 100755
--- a/indra/llmessage/llcurl.h
+++ b/indra/llmessage/llcurl.h
@@ -418,100 +418,6 @@ private:
} ;
-class LLCurlRequest
-{
-public:
- typedef std::vector<std::string> headers_t;
-
- LLCurlRequest();
- ~LLCurlRequest();
-
- void get(const std::string& url, LLCurl::ResponderPtr responder);
- bool getByteRange(const std::string& url, const headers_t& headers, S32 offset, S32 length, LLCurl::ResponderPtr responder);
- bool post(const std::string& url, const headers_t& headers, const LLSD& data, LLCurl::ResponderPtr responder, S32 time_out = 0);
- bool post(const std::string& url, const headers_t& headers, const std::string& data, LLCurl::ResponderPtr responder, S32 time_out = 0);
-
- S32 process();
- S32 getQueued();
-
-private:
- void addMulti();
- LLCurl::Easy* allocEasy();
- bool addEasy(LLCurl::Easy* easy);
-
-private:
- typedef std::set<LLCurl::Multi*> curlmulti_set_t;
- curlmulti_set_t mMultiSet;
- LLCurl::Multi* mActiveMulti;
- S32 mActiveRequestCount;
- BOOL mProcessing;
-};
-
-//for texture fetch only
-class LLCurlTextureRequest : public LLCurlRequest
-{
-public:
- LLCurlTextureRequest(S32 concurrency);
- ~LLCurlTextureRequest();
-
- U32 getByteRange(const std::string& url, const headers_t& headers, S32 offset, S32 length, U32 pri, LLCurl::ResponderPtr responder, F32 delay_time = -1.f);
- void nextRequests();
- void completeRequest(S32 received_bytes);
-
- void updatePriority(U32 handle, U32 pri);
- void removeRequest(U32 handle);
-
- U32 getTotalReceivedBits();
- U32 getTotalIssuedRequests();
- S32 getNumRequests();
- bool isWaiting(U32 handle);
-
-private:
- LLMutex mMutex;
- S32 mConcurrency;
- S32 mInQueue; //request currently in queue.
- U32 mHandleCounter;
- U32 mTotalIssuedRequests;
- U32 mTotalReceivedBits;
-
- typedef struct _request_t
- {
- _request_t(U32 handle, const std::string& url, const headers_t& headers, S32 offset, S32 length, U32 pri, LLCurl::ResponderPtr responder) :
- mHandle(handle), mUrl(url), mHeaders(headers), mOffset(offset), mLength(length), mPriority(pri), mResponder(responder), mStartTime(0.f)
- {}
-
- U32 mHandle;
- std::string mUrl;
- LLCurlRequest::headers_t mHeaders;
- S32 mOffset;
- S32 mLength;
- LLCurl::ResponderPtr mResponder;
- U32 mPriority;
- F32 mStartTime; //start time to issue this request
- } request_t;
-
- struct request_compare
- {
- bool operator()(const request_t* lhs, const request_t* rhs) const
- {
- if(lhs->mPriority != rhs->mPriority)
- {
- return lhs->mPriority > rhs->mPriority; // higher priority in front of queue (set)
- }
- else
- {
- return (U32)lhs < (U32)rhs;
- }
- }
- };
-
- typedef std::set<request_t*, request_compare> req_queue_t;
- req_queue_t mCachedRequests;
- std::map<S32, request_t*> mRequestMap;
-
- LLFrameTimer mGlobalTimer;
-};
-
class LLCurlEasyRequest
{
public:
@@ -550,7 +456,7 @@ private:
namespace LLCurlFF
{
void check_easy_code(CURLcode code);
- void check_multi_code(CURLMcode code);
+ //void check_multi_code(CURLMcode code);
}
#endif // LL_LLCURL_H
diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp
index 200116337d..b4a76cb808 100755
--- a/indra/llmessage/llhttpclient.cpp
+++ b/indra/llmessage/llhttpclient.cpp
@@ -38,6 +38,10 @@
#include "lluri.h"
#include "message.h"
+#include "httpcommon.h"
+#include "httprequest.h"
+#include "httpoptions.h"
+
#include <curl/curl.h>
diff --git a/indra/llmessage/llhttpclientadapter.cpp b/indra/llmessage/llhttpclientadapter.cpp
index b56a804f94..8c2a0ad9cf 100755
--- a/indra/llmessage/llhttpclientadapter.cpp
+++ b/indra/llmessage/llhttpclientadapter.cpp
@@ -26,48 +26,48 @@
#include "llhttpclientadapter.h"
#include "llhttpclient.h"
-
-LLHTTPClientAdapter::~LLHTTPClientAdapter()
-{
-}
-
-void LLHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr responder)
-{
- LLSD empty_pragma_header;
- // Pragma is required to stop curl adding "no-cache"
- // Space is required to stop llurlrequest from turning off proxying
- empty_pragma_header[HTTP_OUT_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;
- if (!empty_pragma_header.has(HTTP_OUT_HEADER_PRAGMA))
- {
- // as above
- empty_pragma_header[HTTP_OUT_HEADER_PRAGMA] = " ";
- }
- LLHTTPClient::get(url, responder, empty_pragma_header);
-}
-
-void LLHTTPClientAdapter::put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder)
-{
- 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);
-}
+//
+// LLHTTPClientAdapter::~LLHTTPClientAdapter()
+// {
+// }
+//
+// void LLHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr responder)
+// {
+// LLSD empty_pragma_header;
+// // Pragma is required to stop curl adding "no-cache"
+// // Space is required to stop llurlrequest from turning off proxying
+// empty_pragma_header[HTTP_OUT_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;
+// if (!empty_pragma_header.has(HTTP_OUT_HEADER_PRAGMA))
+// {
+// // as above
+// empty_pragma_header[HTTP_OUT_HEADER_PRAGMA] = " ";
+// }
+// LLHTTPClient::get(url, responder, empty_pragma_header);
+// }
+//
+// void LLHTTPClientAdapter::put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder)
+// {
+// 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 270282c66f..0067703895 100755
--- a/indra/llmessage/llhttpclientadapter.h
+++ b/indra/llmessage/llhttpclientadapter.h
@@ -30,6 +30,7 @@
#include "llhttpclientinterface.h"
#include "llsingleton.h" // LLSingleton<>
+/*
class LLHTTPClientAdapter : public LLHTTPClientInterface, public LLSingleton<LLHTTPClientAdapter>
{
public:
@@ -46,6 +47,7 @@ public:
const std::string& url,
LLCurl::ResponderPtr responder);
};
+*/
#endif
diff --git a/indra/llmessage/llhttpclientinterface.h b/indra/llmessage/llhttpclientinterface.h
index 12a3857a61..9c1c8e7c11 100755
--- a/indra/llmessage/llhttpclientinterface.h
+++ b/indra/llmessage/llhttpclientinterface.h
@@ -32,14 +32,14 @@
#include <string>
-class LLHTTPClientInterface
-{
-public:
- virtual ~LLHTTPClientInterface() {}
- virtual void get(const std::string& url, LLCurl::ResponderPtr responder) = 0;
- virtual void get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers) = 0;
- virtual void put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder) = 0;
-};
+// class LLHTTPClientInterface
+// {
+// public:
+// virtual ~LLHTTPClientInterface() {}
+// virtual void get(const std::string& url, LLCurl::ResponderPtr responder) = 0;
+// virtual void get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers) = 0;
+// virtual void put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder) = 0;
+// };
#endif // LL_LLHTTPCLIENTINTERFACE_H
diff --git a/indra/llmessage/llhttpsdhandler.cpp b/indra/llmessage/llhttpsdhandler.cpp
new file mode 100644
index 0000000000..159d03b176
--- /dev/null
+++ b/indra/llmessage/llhttpsdhandler.cpp
@@ -0,0 +1,103 @@
+/**
+* @file llhttpsdhandler.h
+* @brief Public-facing declarations for the HttpHandler class
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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 "llhttpconstants.h"
+
+#include "llhttpsdhandler.h"
+#include "httpresponse.h"
+#include "httpheaders.h"
+#include "llsd.h"
+#include "llsdserialize.h"
+#include "bufferstream.h"
+#include "llcorehttputil.h"
+
+//========================================================================
+LLHttpSDHandler::LLHttpSDHandler()
+{
+}
+
+void LLHttpSDHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response)
+{
+ LLCore::HttpStatus status = response->getStatus();
+
+ if (!status)
+ {
+ this->onFailure(response, status);
+ }
+ else
+ {
+ LLSD resplsd;
+ const bool emit_parse_errors = false;
+
+ bool parsed = !((response->getBodySize() == 0) ||
+ !LLCoreHttpUtil::responseToLLSD(response, emit_parse_errors, resplsd));
+
+ if (!parsed)
+ {
+ // Only emit a warning if we failed to parse when 'content-type' == 'application/llsd+xml'
+ LLCore::HttpHeaders::ptr_t headers(response->getHeaders());
+ const std::string *contentType = (headers) ? headers->find(HTTP_IN_HEADER_CONTENT_TYPE) : NULL;
+
+ if (contentType && (HTTP_CONTENT_LLSD_XML == *contentType))
+ {
+ std::string thebody = LLCoreHttpUtil::responseToString(response);
+
+ LL_WARNS() << "Failed to deserialize . " << response->getRequestURL() << " [status:" << response->getStatus().toString() << "] "
+ << " body: " << thebody << LL_ENDL;
+ }
+ }
+
+ this->onSuccess(response, resplsd);
+ }
+
+ // The handler must destroy itself when it is done.
+ // *TODO: I'm not fond of this pattern. A class shooting itself in the head
+ // outside of a smart pointer always makes me nervous.
+ delete this;
+}
+
+//========================================================================
+LLHttpSDGenericHandler::LLHttpSDGenericHandler(const std::string &caps) :
+ LLHttpSDHandler(),
+ mCaps(caps)
+{
+}
+
+void LLHttpSDGenericHandler::onSuccess(LLCore::HttpResponse * response, const LLSD &content)
+{
+ LL_DEBUGS() << mCaps << " Success." << LL_ENDL;
+}
+
+void LLHttpSDGenericHandler::onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status)
+{
+ LL_WARNS()
+ << "\n--------------------------------------------------------------------------\n"
+ << mCaps << " Error[" << status.toULong() << "] cannot access cap with url '"
+ << response->getRequestURL() << "' because " << status.toString()
+ << "\n--------------------------------------------------------------------------"
+ << LL_ENDL;
+}
diff --git a/indra/llmessage/llhttpsdhandler.h b/indra/llmessage/llhttpsdhandler.h
new file mode 100644
index 0000000000..7c28dbcab6
--- /dev/null
+++ b/indra/llmessage/llhttpsdhandler.h
@@ -0,0 +1,67 @@
+/**
+* @file llhttpsdhandler.h
+* @brief Public-facing declarations for the HttpHandler class
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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 _LLHTTPSDHANDLER_H_
+#define _LLHTTPSDHANDLER_H_
+#include "httpcommon.h"
+#include "httphandler.h"
+#include "lluri.h"
+
+/// Handler class LLCore's HTTP library. Splitting with separate success and
+/// failure routines and parsing the result body into LLSD on success. It
+/// is intended to be subclassed for specific capability handling.
+///
+// *TODO: This class self deletes at the end of onCompleted method. This is
+// less than ideal and should be revisited.
+class LLHttpSDHandler : public LLCore::HttpHandler
+{
+public:
+ LLHttpSDHandler();
+
+ virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response);
+
+protected:
+ virtual void onSuccess(LLCore::HttpResponse * response, const LLSD &content) = 0;
+ virtual void onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status) = 0;
+
+};
+
+/// A trivial implementation of LLHttpSDHandler. This success and failure
+/// methods log the action taken, the URI accessed and the status code retuned
+/// in the response.
+class LLHttpSDGenericHandler : public LLHttpSDHandler
+{
+public:
+ LLHttpSDGenericHandler(const std::string &action);
+
+protected:
+ virtual void onSuccess(LLCore::HttpResponse * response, const LLSD &content);
+ virtual void onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status);
+
+private:
+ std::string mCaps;
+};
+#endif \ No newline at end of file
diff --git a/indra/llmessage/llsdrpcclient.h b/indra/llmessage/llsdrpcclient.h
index c4e0333ca3..d097ecdff7 100755
--- a/indra/llmessage/llsdrpcclient.h
+++ b/indra/llmessage/llsdrpcclient.h
@@ -37,7 +37,9 @@
#include "llchainio.h"
#include "llfiltersd2xmlrpc.h"
#include "lliopipe.h"
-#include "llurlrequest.h"
+#if 0
+//#include "llurlrequest.h"
+#endif
/**
* @class LLSDRPCClientResponse
@@ -218,6 +220,7 @@ protected:
LLIOPipe::ptr_t mResponse;
};
+#if 0
/**
* @class LLSDRPCClientFactory
* @brief Basic implementation for making an SD RPC client factory
@@ -267,7 +270,9 @@ public:
protected:
std::string mURL;
};
+#endif
+#if 0
/**
* @class LLXMLSDRPCClientFactory
* @brief Basic implementation for making an XMLRPC to SD RPC client factory
@@ -319,5 +324,6 @@ public:
protected:
std::string mURL;
};
+#endif
#endif // LL_LLSDRPCCLIENT_H
diff --git a/indra/llmessage/tests/llhttpclientadapter_test.cpp b/indra/llmessage/tests/llhttpclientadapter_test.cpp
index e9ce116bb3..e0a82e237b 100755
--- a/indra/llmessage/tests/llhttpclientadapter_test.cpp
+++ b/indra/llmessage/tests/llhttpclientadapter_test.cpp
@@ -23,7 +23,7 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+#if 0
#include "llhttpclientadapter.h"
#include "../test/lltut.h"
@@ -219,3 +219,4 @@ namespace tut
}
}
+#endif \ No newline at end of file