summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rwxr-xr-xindra/newview/CMakeLists.txt43
-rwxr-xr-xindra/newview/app_settings/settings.xml11
-rwxr-xr-xindra/newview/llaccountingcostmanager.cpp263
-rwxr-xr-xindra/newview/llaccountingcostmanager.h12
-rwxr-xr-xindra/newview/llagent.cpp291
-rwxr-xr-xindra/newview/llagent.h29
-rwxr-xr-xindra/newview/llagentlanguage.cpp24
-rwxr-xr-xindra/newview/llappcorehttp.cpp81
-rwxr-xr-xindra/newview/llappcorehttp.h28
-rwxr-xr-xindra/newview/llappearancemgr.cpp527
-rwxr-xr-xindra/newview/llappearancemgr.h25
-rwxr-xr-xindra/newview/llassetuploadresponders.cpp8
-rwxr-xr-xindra/newview/llassetuploadresponders.h7
-rw-r--r--indra/newview/llavatarrenderinfoaccountant.cpp386
-rw-r--r--indra/newview/llavatarrenderinfoaccountant.h13
-rwxr-xr-xindra/newview/llcapabilitylistener.cpp202
-rwxr-xr-xindra/newview/llcapabilitylistener.h131
-rwxr-xr-xindra/newview/llclassifiedstatsresponder.cpp72
-rwxr-xr-xindra/newview/llclassifiedstatsresponder.h50
-rw-r--r--indra/newview/llcoproceduremanager.cpp176
-rw-r--r--indra/newview/llcoproceduremanager.h117
-rwxr-xr-xindra/newview/llestateinfomodel.cpp83
-rwxr-xr-xindra/newview/llestateinfomodel.h5
-rwxr-xr-xindra/newview/lleventpoll.cpp477
-rwxr-xr-xindra/newview/lleventpoll.h18
-rwxr-xr-xindra/newview/llfacebookconnect.cpp664
-rw-r--r--indra/newview/llfacebookconnect.h11
-rwxr-xr-xindra/newview/llfeaturemanager.cpp121
-rwxr-xr-xindra/newview/llfeaturemanager.h3
-rw-r--r--indra/newview/llflickrconnect.cpp583
-rw-r--r--indra/newview/llflickrconnect.h11
-rwxr-xr-xindra/newview/llfloaterabout.cpp99
-rwxr-xr-xindra/newview/llfloaterauction.cpp11
-rwxr-xr-xindra/newview/llfloaterautoreplacesettings.cpp1
-rwxr-xr-xindra/newview/llfloateravatarpicker.cpp58
-rwxr-xr-xindra/newview/llfloateravatarpicker.h3
-rwxr-xr-xindra/newview/llfloaterbvhpreview.cpp20
-rwxr-xr-xindra/newview/llfloaterdisplayname.cpp217
-rwxr-xr-xindra/newview/llfloaterdisplayname.h38
-rwxr-xr-xindra/newview/llfloaterhoverheight.cpp1
-rwxr-xr-xindra/newview/llfloaterimsession.cpp26
-rwxr-xr-xindra/newview/llfloatermodeluploadbase.cpp35
-rwxr-xr-xindra/newview/llfloatermodeluploadbase.h4
-rwxr-xr-xindra/newview/llfloaternamedesc.cpp20
-rwxr-xr-xindra/newview/llfloaterperms.cpp106
-rwxr-xr-xindra/newview/llfloaterperms.h4
-rwxr-xr-xindra/newview/llfloaterregiondebugconsole.cpp105
-rwxr-xr-xindra/newview/llfloaterregiondebugconsole.h7
-rwxr-xr-xindra/newview/llfloaterregioninfo.cpp64
-rwxr-xr-xindra/newview/llfloaterregioninfo.h3
-rwxr-xr-xindra/newview/llfloaterscriptlimits.cpp585
-rwxr-xr-xindra/newview/llfloaterscriptlimits.h58
-rwxr-xr-xindra/newview/llfloatertos.cpp86
-rwxr-xr-xindra/newview/llfloatertos.h5
-rwxr-xr-xindra/newview/llfloaterurlentry.cpp90
-rwxr-xr-xindra/newview/llfloaterurlentry.h7
-rwxr-xr-xindra/newview/llgroupmgr.cpp234
-rwxr-xr-xindra/newview/llgroupmgr.h19
-rwxr-xr-xindra/newview/llhomelocationresponder.cpp108
-rwxr-xr-xindra/newview/llhomelocationresponder.h44
-rwxr-xr-xindra/newview/llhttpretrypolicy.cpp6
-rwxr-xr-xindra/newview/llhttpretrypolicy.h2
-rwxr-xr-xindra/newview/llimview.cpp344
-rwxr-xr-xindra/newview/llimview.h4
-rwxr-xr-xindra/newview/llinventorymodel.cpp136
-rwxr-xr-xindra/newview/llinventorymodel.h26
-rwxr-xr-xindra/newview/llmarketplacefunctions.cpp172
-rwxr-xr-xindra/newview/llmaterialmgr.cpp141
-rw-r--r--indra/newview/llmaterialmgr.h49
-rwxr-xr-xindra/newview/llmediadataclient.cpp569
-rwxr-xr-xindra/newview/llmediadataclient.h145
-rwxr-xr-xindra/newview/llmeshrepository.cpp45
-rwxr-xr-xindra/newview/llmeshrepository.h10
-rwxr-xr-xindra/newview/llpanelclassified.cpp42
-rwxr-xr-xindra/newview/llpanelclassified.h5
-rw-r--r--indra/newview/llpanelexperiencepicker.cpp1
-rwxr-xr-xindra/newview/llpanellandmarks.cpp13
-rwxr-xr-xindra/newview/llpanellogin.cpp1
-rwxr-xr-xindra/newview/llpanelme.cpp1
-rwxr-xr-xindra/newview/llpanelplaceinfo.cpp14
-rwxr-xr-xindra/newview/llpathfindingmanager.cpp667
-rwxr-xr-xindra/newview/llpathfindingmanager.h16
-rwxr-xr-xindra/newview/llpreviewgesture.cpp251
-rwxr-xr-xindra/newview/llpreviewnotecard.cpp130
-rwxr-xr-xindra/newview/llpreviewscript.cpp79
-rwxr-xr-xindra/newview/llpreviewscript.h2
-rwxr-xr-xindra/newview/llproductinforequest.cpp63
-rwxr-xr-xindra/newview/llproductinforequest.h22
-rwxr-xr-xindra/newview/llremoteparcelrequest.cpp108
-rwxr-xr-xindra/newview/llremoteparcelrequest.h24
-rw-r--r--indra/newview/llsnapshotlivepreview.cpp19
-rwxr-xr-xindra/newview/llspeakers.cpp99
-rwxr-xr-xindra/newview/llspeakers.h4
-rw-r--r--indra/newview/llsyntaxid.cpp140
-rw-r--r--indra/newview/llsyntaxid.h10
-rwxr-xr-xindra/newview/lltexturefetch.cpp56
-rwxr-xr-xindra/newview/lltexturefetch.h12
-rw-r--r--indra/newview/lltwitterconnect.cpp562
-rw-r--r--indra/newview/lltwitterconnect.h10
-rwxr-xr-xindra/newview/lluploadfloaterobservers.cpp63
-rwxr-xr-xindra/newview/lluploadfloaterobservers.h14
-rw-r--r--indra/newview/llviewerassetupload.cpp757
-rw-r--r--indra/newview/llviewerassetupload.h208
-rwxr-xr-xindra/newview/llviewerdisplayname.cpp211
-rwxr-xr-xindra/newview/llviewerdisplayname.h53
-rwxr-xr-xindra/newview/llviewerfloaterreg.cpp2
-rwxr-xr-xindra/newview/llviewerinventory.cpp23
-rwxr-xr-xindra/newview/llviewermedia.cpp496
-rwxr-xr-xindra/newview/llviewermedia.h15
-rwxr-xr-xindra/newview/llviewermenufile.cpp585
-rwxr-xr-xindra/newview/llviewermenufile.h58
-rwxr-xr-xindra/newview/llviewerobjectlist.cpp467
-rwxr-xr-xindra/newview/llviewerobjectlist.h10
-rwxr-xr-xindra/newview/llviewerparcelmedia.cpp6
-rwxr-xr-xindra/newview/llviewerparcelmgr.cpp12
-rwxr-xr-xindra/newview/llviewerregion.cpp657
-rwxr-xr-xindra/newview/llviewerregion.h9
-rwxr-xr-xindra/newview/llviewerstats.cpp23
-rwxr-xr-xindra/newview/llvoavatarself.cpp196
-rwxr-xr-xindra/newview/llvoavatarself.h5
-rwxr-xr-xindra/newview/llvoicechannel.cpp137
-rwxr-xr-xindra/newview/llvoicechannel.h4
-rwxr-xr-xindra/newview/llvoicevivox.cpp214
-rwxr-xr-xindra/newview/llvoicevivox.h9
-rwxr-xr-xindra/newview/llwebprofile.cpp358
-rwxr-xr-xindra/newview/llwebprofile.h12
-rwxr-xr-xindra/newview/llwlhandlers.cpp215
-rwxr-xr-xindra/newview/llwlhandlers.h46
-rwxr-xr-xindra/newview/llxmlrpctransaction.cpp500
-rwxr-xr-xindra/newview/llxmlrpctransaction.h4
-rwxr-xr-xindra/newview/tests/llcapabilitylistener_test.cpp271
-rwxr-xr-xindra/newview/tests/llhttpretrypolicy_test.cpp6
-rwxr-xr-xindra/newview/tests/llmediadataclient_test.cpp3
-rwxr-xr-xindra/newview/tests/llremoteparcelrequest_test.cpp2
134 files changed, 7696 insertions, 8485 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 67c00576be..7a6267251e 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -142,7 +142,6 @@ set(viewer_SOURCE_FILES
llbuycurrencyhtml.cpp
llcallbacklist.cpp
llcallingcard.cpp
- llcapabilitylistener.cpp
llcaphttpsender.cpp
llchannelmanager.cpp
llchatbar.cpp
@@ -152,7 +151,6 @@ set(viewer_SOURCE_FILES
llchiclet.cpp
llchicletbar.cpp
llclassifiedinfo.cpp
- llclassifiedstatsresponder.cpp
llcofwearables.cpp
llcolorswatch.cpp
llcommanddispatcherlistener.cpp
@@ -166,6 +164,7 @@ set(viewer_SOURCE_FILES
llconversationloglistitem.cpp
llconversationmodel.cpp
llconversationview.cpp
+ llcoproceduremanager.cpp
llcurrencyuimanager.cpp
llcylinder.cpp
lldateutil.cpp
@@ -234,7 +233,6 @@ set(viewer_SOURCE_FILES
llfloaterconversationpreview.cpp
llfloaterdeleteenvpreset.cpp
llfloaterdestinations.cpp
- llfloaterdisplayname.cpp
llfloatereditdaycycle.cpp
llfloatereditsky.cpp
llfloatereditwater.cpp
@@ -333,7 +331,6 @@ set(viewer_SOURCE_FILES
llgroupmgr.cpp
llhasheduniqueid.cpp
llhints.cpp
- llhomelocationresponder.cpp
llhttpretrypolicy.cpp
llhudeffect.cpp
llhudeffectbeam.cpp
@@ -604,7 +601,6 @@ set(viewer_SOURCE_FILES
lltwitterconnect.cpp
lluilistener.cpp
lluploaddialog.cpp
- lluploadfloaterobservers.cpp
llurl.cpp
llurldispatcher.cpp
llurldispatcherlistener.cpp
@@ -617,6 +613,7 @@ set(viewer_SOURCE_FILES
llviewerassetstats.cpp
llviewerassetstorage.cpp
llviewerassettype.cpp
+ llviewerassetupload.cpp
llviewerattachmenu.cpp
llvieweraudio.cpp
llviewercamera.cpp
@@ -624,7 +621,6 @@ set(viewer_SOURCE_FILES
llviewercontrol.cpp
llviewercontrollistener.cpp
llviewerdisplay.cpp
- llviewerdisplayname.cpp
llviewerfloaterreg.cpp
llviewerfoldertype.cpp
llviewergenericmessage.cpp
@@ -757,7 +753,6 @@ set(viewer_HEADER_FILES
llbuycurrencyhtml.h
llcallbacklist.h
llcallingcard.h
- llcapabilitylistener.h
llcapabilityprovider.h
llcaphttpsender.h
llchannelmanager.h
@@ -768,7 +763,6 @@ set(viewer_HEADER_FILES
llchiclet.h
llchicletbar.h
llclassifiedinfo.h
- llclassifiedstatsresponder.h
llcofwearables.h
llcolorswatch.h
llcommanddispatcherlistener.h
@@ -782,6 +776,7 @@ set(viewer_HEADER_FILES
llconversationloglistitem.h
llconversationmodel.h
llconversationview.h
+ llcoproceduremanager.h
llcurrencyuimanager.h
llcylinder.h
lldateutil.h
@@ -850,7 +845,6 @@ set(viewer_HEADER_FILES
llfloaterconversationpreview.h
llfloaterdeleteenvpreset.h
llfloaterdestinations.h
- llfloaterdisplayname.h
llfloatereditdaycycle.h
llfloatereditsky.h
llfloatereditwater.h
@@ -952,7 +946,6 @@ set(viewer_HEADER_FILES
llhasheduniqueid.h
llhints.h
llhttpretrypolicy.h
- llhomelocationresponder.h
llhudeffect.h
llhudeffectbeam.h
llhudeffectlookat.h
@@ -1225,6 +1218,7 @@ set(viewer_HEADER_FILES
llviewerassetstats.h
llviewerassetstorage.h
llviewerassettype.h
+ llviewerassetupload.h
llviewerattachmenu.h
llvieweraudio.h
llviewercamera.h
@@ -1232,7 +1226,6 @@ set(viewer_HEADER_FILES
llviewercontrol.h
llviewercontrollistener.h
llviewerdisplay.h
- llviewerdisplayname.h
llviewerfloaterreg.h
llviewerfoldertype.h
llviewergenericmessage.h
@@ -2238,9 +2231,9 @@ if (LL_TESTS)
SET(viewer_TEST_SOURCE_FILES
llagentaccess.cpp
lldateutil.cpp
- llmediadataclient.cpp
+# llmediadataclient.cpp
lllogininstance.cpp
- llremoteparcelrequest.cpp
+# llremoteparcelrequest.cpp
lltranslate.cpp
llviewerhelputil.cpp
llversioninfo.cpp
@@ -2271,7 +2264,7 @@ if (LL_TESTS)
set_source_files_properties(
llmediadataclient.cpp
PROPERTIES
- LL_TEST_ADDITIONAL_LIBRARIES "${CURL_LIBRARIES}"
+ LL_TEST_ADDITIONAL_LIBRARIES "${test_libs}"
)
set_source_files_properties(
@@ -2327,7 +2320,6 @@ if (LL_TESTS)
LL_ADD_PROJECT_UNIT_TESTS(${VIEWER_BINARY_NAME} "${viewer_TEST_SOURCE_FILES}")
#set(TEST_DEBUG on)
- set(test_sources llcapabilitylistener.cpp)
##################################################
# DISABLING PRECOMPILED HEADERS USAGE FOR TESTS
##################################################
@@ -2343,26 +2335,29 @@ if (LL_TESTS)
${GOOGLEMOCK_LIBRARIES}
)
- LL_ADD_INTEGRATION_TEST(llcapabilitylistener
- "${test_sources}"
- "${test_libs}"
- ${PYTHON_EXECUTABLE}
- "${CMAKE_SOURCE_DIR}/llmessage/tests/test_llsdmessage_peer.py"
- )
+ if (LINUX)
+ # llcommon uses `clock_gettime' which is provided by librt on linux.
+ set(LIBRT_LIBRARY
+ rt
+ )
+ endif (LINUX)
set(test_libs
- ${LLMESSAGE_LIBRARIES}
- ${LLCOREHTTP_LIBRARIES}
${WINDOWS_LIBRARIES}
${LLVFS_LIBRARIES}
${LLMATH_LIBRARIES}
${LLCOMMON_LIBRARIES}
+ ${LLMESSAGE_LIBRARIES}
+ ${LLCOREHTTP_LIBRARIES}
${GOOGLEMOCK_LIBRARIES}
${OPENSSL_LIBRARIES}
${CRYPTO_LIBRARIES}
+ ${LIBRT_LIBRARY}
+ ${BOOST_CONTEXT_LIBRARY}
+ ${BOOST_COROUTINE_LIBRARY}
)
- LL_ADD_INTEGRATION_TEST(llsechandler_basic
+ LL_ADD_INTEGRATION_TEST(llsechandler_basic
llsechandler_basic.cpp
"${test_libs}"
)
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 9d9bc43bd7..2180a7f1a1 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -2370,6 +2370,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>DebugSlshareLogTag</key>
+ <map>
+ <key>Comment</key>
+ <string>Request slshare-service debug logging</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string/>
+ </map>
<key>DebugStatModeFPS</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llaccountingcostmanager.cpp b/indra/newview/llaccountingcostmanager.cpp
index a42286a9e4..cd9146ea16 100755
--- a/indra/newview/llaccountingcostmanager.cpp
+++ b/indra/newview/llaccountingcostmanager.cpp
@@ -27,90 +27,150 @@
#include "llviewerprecompiledheaders.h"
#include "llaccountingcostmanager.h"
#include "llagent.h"
-#include "llcurl.h"
-#include "llhttpclient.h"
+#include "httpcommon.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
+#include "llcorehttputil.h"
+
//===============================================================================
-LLAccountingCostManager::LLAccountingCostManager()
+LLAccountingCostManager::LLAccountingCostManager():
+ mHttpRequest(),
+ mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID)
{
+ mHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest());
+ //mHttpPolicy = LLCore::HttpRequest::DEFAULT_POLICY_ID;
+
}
-//===============================================================================
-class LLAccountingCostResponder : public LLCurl::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 LLAccountingCostManager::accountingCostCoro(std::string url,
+ eSelectionType selectionType, const LLHandle<LLAccountingCostObserver> observerHandle)
{
- LOG_CLASS(LLAccountingCostResponder);
-public:
- LLAccountingCostResponder( const LLSD& objectIDs, const LLHandle<LLAccountingCostObserver>& observer_handle )
- : mObjectIDs( objectIDs ),
- mObserverHandle( observer_handle )
- {
- LLAccountingCostObserver* observer = mObserverHandle.get();
- if (observer)
- {
- mTransactionID = observer->getTransactionID();
- }
- }
+ LL_DEBUGS("LLAccountingCostManager") << "Entering coroutine " << LLCoros::instance().getName()
+ << " with url '" << url << LL_ENDL;
- void clearPendingRequests ( void )
- {
- for ( LLSD::array_iterator iter = mObjectIDs.beginArray(); iter != mObjectIDs.endArray(); ++iter )
- {
- LLAccountingCostManager::getInstance()->removePendingObject( iter->asUUID() );
- }
- }
-
-protected:
- void httpFailure()
- {
- LL_WARNS() << dumpResponse() << LL_ENDL;
- clearPendingRequests();
-
- LLAccountingCostObserver* observer = mObserverHandle.get();
- if (observer && observer->getTransactionID() == mTransactionID)
- {
- observer->setErrorStatus(getStatus(), getReason());
- }
- }
-
- void httpSuccess()
- {
- const LLSD& content = getContent();
- //Check for error
- if ( !content.isMap() || content.has("error") )
- {
- failureResult(HTTP_INTERNAL_ERROR, "Error on fetched data", content);
- return;
- }
- else if (content.has("selected"))
- {
- F32 physicsCost = 0.0f;
- F32 networkCost = 0.0f;
- F32 simulationCost = 0.0f;
-
- physicsCost = content["selected"]["physics"].asReal();
- networkCost = content["selected"]["streaming"].asReal();
- simulationCost = content["selected"]["simulation"].asReal();
-
- SelectionCost selectionCost( /*transactionID,*/ physicsCost, networkCost, simulationCost );
-
- LLAccountingCostObserver* observer = mObserverHandle.get();
- if (observer && observer->getTransactionID() == mTransactionID)
- {
- observer->onWeightsUpdate(selectionCost);
- }
- }
-
- clearPendingRequests();
- }
-
-private:
- //List of posted objects
- LLSD mObjectIDs;
+ try
+ {
+ LLSD objectList;
+ U32 objectIndex = 0;
+
+ IDIt IDIter = mObjectList.begin();
+ IDIt IDIterEnd = mObjectList.end();
+
+ for (; IDIter != IDIterEnd; ++IDIter)
+ {
+ // Check to see if a request for this object has already been made.
+ if (mPendingObjectQuota.find(*IDIter) == mPendingObjectQuota.end())
+ {
+ mPendingObjectQuota.insert(*IDIter);
+ objectList[objectIndex++] = *IDIter;
+ }
+ }
+
+ mObjectList.clear();
+
+ //Post results
+ if (objectList.size() == 0)
+ return;
+
+ std::string keystr;
+ if (selectionType == Roots)
+ {
+ keystr = "selected_roots";
+ }
+ else if (selectionType == Prims)
+ {
+ keystr = "selected_prims";
+ }
+ else
+ {
+ LL_INFOS() << "Invalid selection type " << LL_ENDL;
+ mObjectList.clear();
+ mPendingObjectQuota.clear();
+ return;
+ }
- // Current request ID
- LLUUID mTransactionID;
+ LLSD dataToPost = LLSD::emptyMap();
+ dataToPost[keystr.c_str()] = objectList;
+
+ LLAccountingCostObserver* observer = observerHandle.get();
+ LLUUID transactionId = observer->getTransactionID();
+ observer = NULL;
+
+ LLCoreHttpUtil::HttpCoroutineAdapter httpAdapter("AccountingCost", mHttpPolicy);
+
+ LLSD results = httpAdapter.postAndYield(mHttpRequest, url, dataToPost);
+
+ LLSD httpResults;
+ httpResults = results["http_result"];
+
+ // do/while(false) allows error conditions to break out of following
+ // block while normal flow goes forward once.
+ do
+ {
+ observer = observerHandle.get();
+ if ((!observer) || (observer->getTransactionID() != transactionId))
+ { // *TODO: Rider: I've noticed that getTransactionID() does not
+ // always match transactionId (the new transaction Id does not show a
+ // corresponding request.) (ask Vir)
+ if (!observer)
+ break;
+ LL_WARNS() << "Request transaction Id(" << transactionId
+ << ") does not match observer's transaction Id("
+ << observer->getTransactionID() << ")." << LL_ENDL;
+ break;
+ }
+
+ if (!httpResults["success"].asBoolean())
+ {
+ LL_WARNS() << "Error result from LLCoreHttpUtil::HttpCoroHandler. Code "
+ << httpResults["status"] << ": '" << httpResults["message"] << "'" << LL_ENDL;
+ if (observer)
+ {
+ observer->setErrorStatus(httpResults["status"].asInteger(), httpResults["message"].asStringRef());
+ }
+ break;
+ }
+
+ if (!results.isMap() || results.has("error"))
+ {
+ LL_WARNS() << "Error on fetched data" << LL_ENDL;
+ observer->setErrorStatus(499, "Error on fetched data");
+ break;
+ }
+
+ if (results.has("selected"))
+ {
+ F32 physicsCost = 0.0f;
+ F32 networkCost = 0.0f;
+ F32 simulationCost = 0.0f;
+
+ physicsCost = results["selected"]["physics"].asReal();
+ networkCost = results["selected"]["streaming"].asReal();
+ simulationCost = results["selected"]["simulation"].asReal();
+
+ SelectionCost selectionCost( physicsCost, networkCost, simulationCost);
+
+ observer->onWeightsUpdate(selectionCost);
+ }
+
+ } while (false);
+
+ }
+ catch (std::exception e)
+ {
+ LL_WARNS() << "Caught exception '" << e.what() << "'" << LL_ENDL;
+ }
+ catch (...)
+ {
+ LL_WARNS() << "Caught unknown exception." << LL_ENDL;
+ }
+
+ mPendingObjectQuota.clear();
+}
- // Cost update observer handle
- LLHandle<LLAccountingCostObserver> mObserverHandle;
-};
//===============================================================================
void LLAccountingCostManager::fetchCosts( eSelectionType selectionType,
const std::string& url,
@@ -119,50 +179,11 @@ void LLAccountingCostManager::fetchCosts( eSelectionType selectionType,
// Invoking system must have already determined capability availability
if ( !url.empty() )
{
- LLSD objectList;
- U32 objectIndex = 0;
-
- IDIt IDIter = mObjectList.begin();
- IDIt IDIterEnd = mObjectList.end();
-
- for ( ; IDIter != IDIterEnd; ++IDIter )
- {
- // Check to see if a request for this object has already been made.
- if ( mPendingObjectQuota.find( *IDIter ) == mPendingObjectQuota.end() )
- {
- mPendingObjectQuota.insert( *IDIter );
- objectList[objectIndex++] = *IDIter;
- }
- }
-
- mObjectList.clear();
-
- //Post results
- if ( objectList.size() > 0 )
- {
- std::string keystr;
- if ( selectionType == Roots )
- {
- keystr="selected_roots";
- }
- else
- if ( selectionType == Prims )
- {
- keystr="selected_prims";
- }
- else
- {
- LL_INFOS()<<"Invalid selection type "<<LL_ENDL;
- mObjectList.clear();
- mPendingObjectQuota.clear();
- return;
- }
-
- LLSD dataToPost = LLSD::emptyMap();
- dataToPost[keystr.c_str()] = objectList;
-
- LLHTTPClient::post( url, dataToPost, new LLAccountingCostResponder( objectList, observer_handle ));
- }
+ std::string coroname =
+ LLCoros::instance().launch("LLAccountingCostManager::accountingCostCoro",
+ boost::bind(&LLAccountingCostManager::accountingCostCoro, this, url, selectionType, observer_handle));
+ LL_DEBUGS() << coroname << " with url '" << url << LL_ENDL;
+
}
else
{
diff --git a/indra/newview/llaccountingcostmanager.h b/indra/newview/llaccountingcostmanager.h
index 3ade34c81d..d5a94f6fda 100755
--- a/indra/newview/llaccountingcostmanager.h
+++ b/indra/newview/llaccountingcostmanager.h
@@ -30,6 +30,13 @@
#include "llhandle.h"
#include "llaccountingcost.h"
+#include "httpcommon.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
+#include "httprequest.h"
+#include "httpheaders.h"
+#include "httpoptions.h"
+
//===============================================================================
// An interface class for panels which display the parcel accounting information.
class LLAccountingCostObserver
@@ -69,6 +76,11 @@ private:
//a fetch has been instigated.
std::set<LLUUID> mPendingObjectQuota;
typedef std::set<LLUUID>::iterator IDIt;
+
+ void accountingCostCoro(std::string url, eSelectionType selectionType, const LLHandle<LLAccountingCostObserver> observerHandle);
+
+ LLCore::HttpRequest::ptr_t mHttpRequest;
+ LLCore::HttpRequest::policy_t mHttpPolicy;
};
//===============================================================================
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 359171c5bd..2060065c75 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -38,7 +38,6 @@
#include "llappearancemgr.h"
#include "llanimationstates.h"
#include "llcallingcard.h"
-#include "llcapabilitylistener.h"
#include "llchannelmanager.h"
#include "llchicletbar.h"
#include "llconsole.h"
@@ -52,7 +51,6 @@
#include "llfloatertools.h"
#include "llgroupactions.h"
#include "llgroupmgr.h"
-#include "llhomelocationresponder.h"
#include "llhudmanager.h"
#include "lljoystickbutton.h"
#include "llmorphview.h"
@@ -63,7 +61,6 @@
#include "llpaneltopinfobar.h"
#include "llparcel.h"
#include "llrendersphere.h"
-#include "llsdmessage.h"
#include "llsdutil.h"
#include "llsky.h"
#include "llslurl.h"
@@ -95,6 +92,7 @@
#include "lscript_byteformat.h"
#include "stringize.h"
#include "boost/foreach.hpp"
+#include "llcorehttputil.h"
using namespace LLAvatarAppearanceDefines;
@@ -361,7 +359,8 @@ LLAgent::LLAgent() :
mMaturityPreferenceNumRetries(0U),
mLastKnownRequestMaturity(SIM_ACCESS_MIN),
mLastKnownResponseMaturity(SIM_ACCESS_MIN),
- mTeleportState( TELEPORT_NONE ),
+ mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID),
+ mTeleportState(TELEPORT_NONE),
mRegionp(NULL),
mAgentOriginGlobal(),
@@ -461,6 +460,10 @@ void LLAgent::init()
mTeleportFailedSlot = LLViewerParcelMgr::getInstance()->setTeleportFailedCallback(boost::bind(&LLAgent::handleTeleportFailed, this));
}
+ LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp());
+
+ mHttpPolicy = app_core_http.getPolicy(LLAppCoreHttp::AP_AGENT);
+
mInitialized = TRUE;
}
@@ -2326,27 +2329,9 @@ void LLAgent::setStartPosition( U32 location_id )
body["HomeLocation"] = homeLocation;
- // This awkward idiom warrants explanation.
- // For starters, LLSDMessage::ResponderAdapter is ONLY for testing the new
- // LLSDMessage functionality with a pre-existing LLHTTPClient::Responder.
- // In new code, define your reply/error methods on the same class as the
- // sending method, bind them to local LLEventPump objects and pass those
- // LLEventPump names in the request LLSD object.
- // When testing old code, the new LLHomeLocationResponder object
- // is referenced by an LLHTTPClient::ResponderPtr, so when the
- // ResponderAdapter is deleted, the LLHomeLocationResponder will be too.
- // We must trust that the underlying LLHTTPClient code will eventually
- // fire either the reply callback or the error callback; either will cause
- // the ResponderAdapter to delete itself.
- LLSDMessage::ResponderAdapter*
- adapter(new LLSDMessage::ResponderAdapter(new LLHomeLocationResponder()));
-
- request["message"] = "HomeLocation";
- request["payload"] = body;
- request["reply"] = adapter->getReplyName();
- request["error"] = adapter->getErrorName();
-
- gAgent.getRegion()->getCapAPI().post(request);
+ if (!requestPostCapability("HomeLocation", body,
+ boost::bind(&LLAgent::setStartPositionSuccess, this, _1)))
+ LL_WARNS() << "Unable to post to HomeLocation capability." << LL_ENDL;
const U32 HOME_INDEX = 1;
if( HOME_INDEX == location_id )
@@ -2355,32 +2340,51 @@ void LLAgent::setStartPosition( U32 location_id )
}
}
-struct HomeLocationMapper: public LLCapabilityListener::CapabilityMapper
+void LLAgent::setStartPositionSuccess(const LLSD &result)
{
- // No reply message expected
- HomeLocationMapper(): LLCapabilityListener::CapabilityMapper("HomeLocation") {}
- virtual void buildMessage(LLMessageSystem* msg,
- const LLUUID& agentID,
- const LLUUID& sessionID,
- const std::string& capabilityName,
- const LLSD& payload) const
+ 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 (!result.has("success"))
+ break;
+
+ if (0 != strncmp("true", result["success"].asString().c_str(), 4))
+ break;
+
+ // did the simulator return a "justified" home location?
+ // If no, we keep error set to true
+ if (!result.has("HomeLocation"))
+ break;
+
+ if ((!result["HomeLocation"].has("LocationPos")) ||
+ (!result["HomeLocation"]["LocationPos"].has("X")) ||
+ (!result["HomeLocation"]["LocationPos"].has("Y")) ||
+ (!result["HomeLocation"]["LocationPos"].has("Z")))
+ break;
+
+ agent_pos.mV[VX] = result["HomeLocation"]["LocationPos"]["X"].asInteger();
+ agent_pos.mV[VY] = result["HomeLocation"]["LocationPos"]["Y"].asInteger();
+ agent_pos.mV[VZ] = result["HomeLocation"]["LocationPos"]["Z"].asInteger();
+
+ error = false;
+
+ } while (0);
+
+ if (error)
{
- msg->newMessageFast(_PREHASH_SetStartLocationRequest);
- msg->nextBlockFast( _PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, agentID);
- msg->addUUIDFast(_PREHASH_SessionID, sessionID);
- msg->nextBlockFast( _PREHASH_StartLocationData);
- // corrected by sim
- msg->addStringFast(_PREHASH_SimName, "");
- msg->addU32Fast(_PREHASH_LocationID, payload["HomeLocation"]["LocationId"].asInteger());
- msg->addVector3Fast(_PREHASH_LocationPos,
- ll_vector3_from_sdmap(payload["HomeLocation"]["LocationPos"]));
- msg->addVector3Fast(_PREHASH_LocationLookAt,
- ll_vector3_from_sdmap(payload["HomeLocation"]["LocationLookAt"]));
+ LL_WARNS() << "Error in response to home position set." << LL_ENDL;
}
-};
-// Need an instance of this class so it will self-register
-static HomeLocationMapper homeLocationMapper;
+ else
+ {
+ LL_INFOS() << "setting home position" << LL_ENDL;
+
+ LLViewerRegion *viewer_region = gAgent.getRegion();
+ setHomePosRegion(viewer_region->getHandle(), agent_pos);
+ }
+}
void LLAgent::requestStopMotion( LLMotion* motion )
{
@@ -2517,87 +2521,6 @@ int LLAgent::convertTextToMaturity(char text)
return LLAgentAccess::convertTextToMaturity(text);
}
-class LLMaturityPreferencesResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(LLMaturityPreferencesResponder);
-public:
- LLMaturityPreferencesResponder(LLAgent *pAgent, U8 pPreferredMaturity, U8 pPreviousMaturity);
- virtual ~LLMaturityPreferencesResponder();
-
-protected:
- virtual void httpSuccess();
- virtual void httpFailure();
-
-protected:
-
-private:
- U8 parseMaturityFromServerResponse(const LLSD &pContent) const;
-
- LLAgent *mAgent;
- U8 mPreferredMaturity;
- U8 mPreviousMaturity;
-};
-
-LLMaturityPreferencesResponder::LLMaturityPreferencesResponder(LLAgent *pAgent, U8 pPreferredMaturity, U8 pPreviousMaturity)
- : LLHTTPClient::Responder(),
- mAgent(pAgent),
- mPreferredMaturity(pPreferredMaturity),
- mPreviousMaturity(pPreviousMaturity)
-{
-}
-
-LLMaturityPreferencesResponder::~LLMaturityPreferencesResponder()
-{
-}
-
-void LLMaturityPreferencesResponder::httpSuccess()
-{
- U8 actualMaturity = parseMaturityFromServerResponse(getContent());
-
- if (actualMaturity != mPreferredMaturity)
- {
- LL_WARNS() << "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() << LL_ENDL;
- }
- mAgent->handlePreferredMaturityResult(actualMaturity);
-}
-
-void LLMaturityPreferencesResponder::httpFailure()
-{
- LL_WARNS() << "while attempting to change maturity preference from '"
- << LLViewerRegion::accessToString(mPreviousMaturity)
- << "' to '" << LLViewerRegion::accessToString(mPreferredMaturity)
- << "', " << dumpResponse() << LL_ENDL;
- mAgent->handlePreferredMaturityError();
-}
-
-U8 LLMaturityPreferencesResponder::parseMaturityFromServerResponse(const LLSD &pContent) const
-{
- U8 maturity = SIM_ACCESS_MIN;
-
- llassert(pContent.isDefined());
- llassert(pContent.isMap());
- llassert(pContent.has("access_prefs"));
- llassert(pContent.get("access_prefs").isMap());
- llassert(pContent.get("access_prefs").has("max"));
- llassert(pContent.get("access_prefs").get("max").isString());
- if (pContent.isDefined() && pContent.isMap() && pContent.has("access_prefs")
- && pContent.get("access_prefs").isMap() && pContent.get("access_prefs").has("max")
- && pContent.get("access_prefs").get("max").isString())
- {
- LLSD::String actualPreference = pContent.get("access_prefs").get("max").asString();
- LLStringUtil::trim(actualPreference);
- maturity = LLViewerRegion::shortStringToAccess(actualPreference);
- }
-
- return maturity;
-}
-
void LLAgent::handlePreferredMaturityResult(U8 pServerMaturity)
{
// Update the number of responses received
@@ -2726,42 +2649,96 @@ void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity)
// Update the last know maturity request
mLastKnownRequestMaturity = pPreferredMaturity;
- // Create a response handler
- LLHTTPClient::ResponderPtr responderPtr = LLHTTPClient::ResponderPtr(new LLMaturityPreferencesResponder(this, pPreferredMaturity, mLastKnownResponseMaturity));
-
// If we don't have a region, report it as an error
if (getRegion() == NULL)
{
- responderPtr->failureResult(0U, "region is not defined", LLSD());
+ LL_WARNS("Agent") << "Region is not defined, can not change Maturity setting." << LL_ENDL;
+ return;
}
- else
- {
- // Find the capability to send maturity preference
- std::string url = getRegion()->getCapability("UpdateAgentInformation");
- // If the capability is not defined, report it as an error
- if (url.empty())
- {
- responderPtr->failureResult(0U,
- "capability 'UpdateAgentInformation' is not defined for region", LLSD());
- }
- else
- {
- // Set new access preference
- LLSD access_prefs = LLSD::emptyMap();
- access_prefs["max"] = LLViewerRegion::accessToShortString(pPreferredMaturity);
-
- LLSD body = LLSD::emptyMap();
- body["access_prefs"] = access_prefs;
- LL_INFOS() << "Sending viewer preferred maturity to '" << LLViewerRegion::accessToString(pPreferredMaturity)
- << "' via capability to: " << url << LL_ENDL;
- LLSD headers;
- LLHTTPClient::post(url, body, responderPtr, headers, 30.0f);
- }
- }
+ LLSD access_prefs = LLSD::emptyMap();
+ access_prefs["max"] = LLViewerRegion::accessToShortString(pPreferredMaturity);
+
+ LLSD postData = LLSD::emptyMap();
+ postData["access_prefs"] = access_prefs;
+ LL_INFOS() << "Sending viewer preferred maturity to '" << LLViewerRegion::accessToString(pPreferredMaturity) << LL_ENDL;
+
+ if (!requestPostCapability("UpdateAgentInformation", postData,
+ static_cast<httpCallback_t>(boost::bind(&LLAgent::processMaturityPreferenceFromServer, this, _1, pPreferredMaturity)),
+ static_cast<httpCallback_t>(boost::bind(&LLAgent::handlePreferredMaturityError, this))
+ ))
+ {
+ LL_WARNS("Agent") << "Maturity request post failed." << LL_ENDL;
+ }
}
}
+
+void LLAgent::processMaturityPreferenceFromServer(const LLSD &result, U8 perferredMaturity)
+{
+ U8 maturity = SIM_ACCESS_MIN;
+
+ llassert(result.isDefined());
+ llassert(result.isMap());
+ llassert(result.has("access_prefs"));
+ llassert(result.get("access_prefs").isMap());
+ llassert(result.get("access_prefs").has("max"));
+ llassert(result.get("access_prefs").get("max").isString());
+ if (result.isDefined() && result.isMap() && result.has("access_prefs")
+ && result.get("access_prefs").isMap() && result.get("access_prefs").has("max")
+ && result.get("access_prefs").get("max").isString())
+ {
+ LLSD::String actualPreference = result.get("access_prefs").get("max").asString();
+ LLStringUtil::trim(actualPreference);
+ maturity = LLViewerRegion::shortStringToAccess(actualPreference);
+ }
+
+ if (maturity != perferredMaturity)
+ {
+ LL_WARNS() << "while attempting to change maturity preference from '"
+ << LLViewerRegion::accessToString(mLastKnownResponseMaturity)
+ << "' to '" << LLViewerRegion::accessToString(perferredMaturity)
+ << "', the server responded with '"
+ << LLViewerRegion::accessToString(maturity)
+ << "' [value:" << static_cast<U32>(maturity)
+ << "], " << LL_ENDL;
+ }
+ handlePreferredMaturityResult(maturity);
+}
+
+
+bool LLAgent::requestPostCapability(const std::string &capName, LLSD &postData, httpCallback_t cbSuccess, httpCallback_t cbFailure)
+{
+ std::string url;
+
+ url = getRegion()->getCapability(capName);
+
+ if (url.empty())
+ {
+ LL_WARNS("Agent") << "Could not retrieve region capability \"" << capName << "\"" << LL_ENDL;
+ return false;
+ }
+
+ LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(url, mHttpPolicy, postData, cbSuccess, cbFailure);
+ return true;
+}
+
+bool LLAgent::requestGetCapability(const std::string &capName, httpCallback_t cbSuccess, httpCallback_t cbFailure)
+{
+ std::string url;
+
+ url = getRegion()->getCapability(capName);
+
+ if (url.empty())
+ {
+ LL_WARNS("Agent") << "Could not retrieve region capability \"" << capName << "\"" << LL_ENDL;
+ return false;
+ }
+
+ LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpGet(url, mHttpPolicy, cbSuccess, cbFailure);
+ return true;
+}
+
BOOL LLAgent::getAdminOverride() const
{
return mAgentAccess->getAdminOverride();
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 4830cb754b..0ba3dea427 100755
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -34,7 +34,9 @@
#include "llcoordframe.h" // for mFrameAgent
#include "llavatarappearancedefines.h"
#include "llpermissionsflags.h"
+#include "llevents.h"
#include "v3dmath.h"
+#include "llcorehttputil.h"
#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>
@@ -61,6 +63,8 @@ class LLPauseRequestHandle;
class LLUIColor;
class LLTeleportRequest;
+
+
typedef boost::shared_ptr<LLTeleportRequest> LLTeleportRequestPtr;
//--------------------------------------------------------------------
@@ -112,6 +116,8 @@ public:
void init();
void cleanup();
+private:
+
//--------------------------------------------------------------------
// Login
//--------------------------------------------------------------------
@@ -227,6 +233,8 @@ public:
void setHomePosRegion(const U64& region_handle, const LLVector3& pos_region);
BOOL getHomePosGlobal(LLVector3d* pos_global);
private:
+ void setStartPositionSuccess(const LLSD &result);
+
BOOL mHaveHomePosition;
U64 mHomeRegionHandle;
LLVector3 mHomePosRegion;
@@ -631,6 +639,8 @@ public:
void setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange);
private:
+
+
friend class LLTeleportRequest;
friend class LLTeleportRequestViaLandmark;
friend class LLTeleportRequestViaLure;
@@ -758,11 +768,12 @@ private:
unsigned int mMaturityPreferenceNumRetries;
U8 mLastKnownRequestMaturity;
U8 mLastKnownResponseMaturity;
+ LLCore::HttpRequest::policy_t mHttpPolicy;
bool isMaturityPreferenceSyncedWithServer() const;
void sendMaturityPreferenceToServer(U8 pPreferredMaturity);
+ void processMaturityPreferenceFromServer(const LLSD &result, U8 perferredMaturity);
- friend class LLMaturityPreferencesResponder;
void handlePreferredMaturityResult(U8 pServerMaturity);
void handlePreferredMaturityError();
void reportPreferredMaturitySuccess();
@@ -911,6 +922,22 @@ public:
/********************************************************************************
** **
+ ** UTILITY
+ **/
+public:
+ typedef LLCoreHttpUtil::HttpCoroutineAdapter::completionCallback_t httpCallback_t;
+
+ /// Utilities for allowing the the agent sub managers to post and get via
+ /// HTTP using the agent's policy settings and headers.
+ bool requestPostCapability(const std::string &capName, LLSD &postData, httpCallback_t cbSuccess = NULL, httpCallback_t cbFailure = NULL);
+ bool requestGetCapability(const std::string &capName, httpCallback_t cbSuccess = NULL, httpCallback_t cbFailure = NULL);
+
+/** Utility
+ ** **
+ *******************************************************************************/
+
+/********************************************************************************
+ ** **
** DEBUGGING
**/
diff --git a/indra/newview/llagentlanguage.cpp b/indra/newview/llagentlanguage.cpp
index fe6236a32a..cdb0e3302d 100755
--- a/indra/newview/llagentlanguage.cpp
+++ b/indra/newview/llagentlanguage.cpp
@@ -32,6 +32,7 @@
#include "llviewerregion.h"
// library includes
#include "llui.h" // getLanguage()
+#include "httpcommon.h"
// static
void LLAgentLanguage::init()
@@ -54,22 +55,17 @@ void LLAgentLanguage::onChange()
// static
bool LLAgentLanguage::update()
{
- LLSD body;
- std::string url;
+ LLSD body;
- if (gAgent.getRegion())
- {
- url = gAgent.getRegion()->getCapability("UpdateAgentLanguage");
- }
-
- if (!url.empty())
- {
- std::string language = LLUI::getLanguage();
+ std::string language = LLUI::getLanguage();
- body["language"] = language;
- body["language_is_public"] = gSavedSettings.getBOOL("LanguageIsPublic");
+ body["language"] = language;
+ body["language_is_public"] = gSavedSettings.getBOOL("LanguageIsPublic");
- LLHTTPClient::post(url, body, new LLHTTPClient::Responder);
- }
+ if (!gAgent.requestPostCapability("UpdateAgentLanguage", body))
+ {
+ LL_WARNS("Language") << "Language capability unavailable." << LL_ENDL;
+ }
+
return true;
}
diff --git a/indra/newview/llappcorehttp.cpp b/indra/newview/llappcorehttp.cpp
index f5f224b83e..51cca273d8 100755
--- a/indra/newview/llappcorehttp.cpp
+++ b/indra/newview/llappcorehttp.cpp
@@ -31,6 +31,10 @@
#include "llappviewer.h"
#include "llviewercontrol.h"
+#include <openssl/x509_vfy.h>
+#include <openssl/ssl.h>
+#include "llsecapi.h"
+#include <curl/curl.h>
// Here is where we begin to get our connection usage under control.
// This establishes llcorehttp policy classes that, among other
@@ -93,6 +97,16 @@ static const struct
4, 1, 4, 0, false,
"",
"inventory"
+ },
+ { // AP_MATERIALS
+ 2, 1, 8, 0, false,
+ "RenderMaterials",
+ "material manager requests"
+ },
+ { // AP_AGENT
+ 2, 1, 32, 0, true,
+ "Agent",
+ "Agent requests"
}
};
@@ -151,6 +165,15 @@ void LLAppCoreHttp::init()
<< LL_ENDL;
}
+ // Set up SSL Verification call back.
+ status = LLCore::HttpRequest::setStaticPolicyOption(LLCore::HttpRequest::PO_SSL_VERIFY_CALLBACK,
+ LLCore::HttpRequest::GLOBAL_POLICY_ID,
+ sslVerify, NULL);
+ if (!status)
+ {
+ LL_WARNS("Init") << "Failed to set SSL Verification. Reason: " << status.toString() << LL_ENDL;
+ }
+
// Tracing levels for library & libcurl (note that 2 & 3 are beyond spammy):
// 0 - None
// 1 - Basic start, stop simple transitions
@@ -182,6 +205,8 @@ void LLAppCoreHttp::init()
}
mHttpClasses[app_policy].mPolicy = LLCore::HttpRequest::createPolicyClass();
+ // We have run out of available HTTP policies. Adjust HTTP_POLICY_CLASS_LIMIT in _httpinternal.h
+ llassert(mHttpClasses[app_policy].mPolicy != LLCore::HttpRequest::INVALID_POLICY_ID);
if (! mHttpClasses[app_policy].mPolicy)
{
// Use default policy (but don't accidentally modify default)
@@ -457,6 +482,62 @@ void LLAppCoreHttp::refreshSettings(bool initial)
}
}
+LLCore::HttpStatus LLAppCoreHttp::sslVerify(const std::string &url,
+ LLCore::HttpHandler const * const handler, void *appdata)
+{
+ X509_STORE_CTX *ctx = static_cast<X509_STORE_CTX *>(appdata);
+ LLCore::HttpStatus result;
+ LLPointer<LLCertificateStore> store = gSecAPIHandler->getCertificateStore("");
+ LLPointer<LLCertificateChain> chain = gSecAPIHandler->getCertificateChain(ctx);
+ LLSD validation_params = LLSD::emptyMap();
+ LLURI uri(url);
+
+ validation_params[CERT_HOSTNAME] = uri.hostName();
+
+ // *TODO: In the case of an exception while validating the cert, we need a way
+ // to pass the offending(?) cert back out. *Rider*
+
+ try
+ {
+ // don't validate hostname. Let libcurl do it instead. That way, it'll handle redirects
+ store->validate(VALIDATION_POLICY_SSL & (~VALIDATION_POLICY_HOSTNAME), chain, validation_params);
+ }
+ catch (LLCertValidationTrustException &cert_exception)
+ {
+ // this exception is is handled differently than the general cert
+ // exceptions, as we allow the user to actually add the certificate
+ // for trust.
+ // therefore we pass back a different error code
+ // NOTE: We're currently 'wired' to pass around CURL error codes. This is
+ // somewhat clumsy, as we may run into errors that do not map directly to curl
+ // error codes. Should be refactored with login refactoring, perhaps.
+ result = LLCore::HttpStatus(LLCore::HttpStatus::EXT_CURL_EASY, CURLE_SSL_CACERT);
+ result.setMessage(cert_exception.getMessage());
+ LLPointer<LLCertificate> cert = cert_exception.getCert();
+ cert->ref(); // adding an extra ref here
+ result.setErrorData(cert.get());
+ // We should probably have a more generic way of passing information
+ // back to the error handlers.
+ }
+ catch (LLCertException &cert_exception)
+ {
+ result = LLCore::HttpStatus(LLCore::HttpStatus::EXT_CURL_EASY, CURLE_SSL_PEER_CERTIFICATE);
+ result.setMessage(cert_exception.getMessage());
+ LLPointer<LLCertificate> cert = cert_exception.getCert();
+ cert->ref(); // adding an extra ref here
+ result.setErrorData(cert.get());
+ }
+ catch (...)
+ {
+ // any other odd error, we just handle as a connect error.
+ result = LLCore::HttpStatus(LLCore::HttpStatus::EXT_CURL_EASY, CURLE_SSL_CONNECT_ERROR);
+ }
+
+ return result;
+}
+
+
+
void LLAppCoreHttp::onCompleted(LLCore::HttpHandle, LLCore::HttpResponse *)
{
diff --git a/indra/newview/llappcorehttp.h b/indra/newview/llappcorehttp.h
index 37d7a737e7..410d7c6b07 100755
--- a/indra/newview/llappcorehttp.h
+++ b/indra/newview/llappcorehttp.h
@@ -164,7 +164,29 @@ public:
/// Pipelined: no
AP_INVENTORY,
AP_REPORTING = AP_INVENTORY, // Piggy-back on inventory
-
+
+ /// Material resource requests and puts.
+ ///
+ /// Destination: simhost:12043
+ /// Protocol: https:
+ /// Transfer size: KB
+ /// Long poll: no
+ /// Concurrency: low
+ /// Request rate: low
+ /// Pipelined: no
+ AP_MATERIALS,
+
+ /// Appearance resource requests and puts.
+ ///
+ /// Destination: simhost:12043
+ /// Protocol: https:
+ /// Transfer size: KB
+ /// Long poll: no
+ /// Concurrency: mid
+ /// Request rate: low
+ /// Pipelined: yes
+ AP_AGENT,
+
AP_COUNT // Must be last
};
@@ -233,7 +255,9 @@ private:
bool mStopped;
HttpClass mHttpClasses[AP_COUNT];
bool mPipelined; // Global setting
- boost::signals2::connection mPipelinedSignal; // Signal for 'HttpPipelining' setting
+ boost::signals2::connection mPipelinedSignal; // Signal for 'HttpPipelining' setting
+
+ static LLCore::HttpStatus sslVerify(const std::string &uri, LLCore::HttpHandler const * const handler, void *appdata);
};
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 3be705dd95..ff420a3600 100755
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -23,7 +23,7 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
#include "llviewerprecompiledheaders.h"
#include <boost/lexical_cast.hpp>
@@ -54,6 +54,9 @@
#include "llsdserialize.h"
#include "llhttpretrypolicy.h"
#include "llaisapi.h"
+#include "llhttpsdhandler.h"
+#include "llcorehttputil.h"
+#include "llappviewer.h"
#if LL_MSVC
// disable boost::lexical_cast warning
@@ -1257,6 +1260,8 @@ static void removeDuplicateItems(LLInventoryModel::item_array_t& items)
items = new_items;
}
+//=========================================================================
+
const LLUUID LLAppearanceMgr::getCOF() const
{
return gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
@@ -3261,276 +3266,6 @@ void LLAppearanceMgr::updateClothingOrderingInfo(LLUUID cat_id,
}
-class RequestAgentUpdateAppearanceResponder: public LLHTTPClient::Responder
-{
- LOG_CLASS(RequestAgentUpdateAppearanceResponder);
-
- friend class LLAppearanceMgr;
-
-public:
- RequestAgentUpdateAppearanceResponder();
-
- virtual ~RequestAgentUpdateAppearanceResponder();
-
-private:
- // Called when sendServerAppearanceUpdate called. May or may not
- // trigger a request depending on various bits of state.
- void onRequestRequested();
-
- // Post the actual appearance request to cap.
- void sendRequest();
-
- void debugCOF(const LLSD& content);
-
-protected:
- // Successful completion.
- /* virtual */ void httpSuccess();
-
- // Error
- /*virtual*/ void httpFailure();
-
- void onFailure();
- void onSuccess();
-
- S32 mInFlightCounter;
- LLTimer mInFlightTimer;
- LLPointer<LLHTTPRetryPolicy> mRetryPolicy;
-};
-
-RequestAgentUpdateAppearanceResponder::RequestAgentUpdateAppearanceResponder()
-{
- bool retry_on_4xx = true;
- mRetryPolicy = new LLAdaptiveRetryPolicy(1.0, 32.0, 2.0, 10, retry_on_4xx);
- mInFlightCounter = 0;
-}
-
-RequestAgentUpdateAppearanceResponder::~RequestAgentUpdateAppearanceResponder()
-{
-}
-
-void RequestAgentUpdateAppearanceResponder::onRequestRequested()
-{
- // If we have already received an update for this or higher cof version, ignore.
- S32 cof_version = LLAppearanceMgr::instance().getCOFVersion();
- S32 last_rcv = gAgentAvatarp->mLastUpdateReceivedCOFVersion;
- S32 last_req = gAgentAvatarp->mLastUpdateRequestCOFVersion;
- LL_DEBUGS("Avatar") << "cof_version " << cof_version
- << " last_rcv " << last_rcv
- << " last_req " << last_req
- << " in flight " << mInFlightCounter << LL_ENDL;
- if ((mInFlightCounter>0) && (mInFlightTimer.hasExpired()))
- {
- LL_WARNS("Avatar") << "in flight timer expired, resetting " << LL_ENDL;
- mInFlightCounter = 0;
- }
- if (cof_version < last_rcv)
- {
- LL_DEBUGS("Avatar") << "Have already received update for cof version " << last_rcv
- << " will not request for " << cof_version << LL_ENDL;
- return;
- }
- if (mInFlightCounter>0 && last_req >= cof_version)
- {
- LL_DEBUGS("Avatar") << "Request already in flight for cof version " << last_req
- << " will not request for " << cof_version << LL_ENDL;
- return;
- }
-
- // Actually send the request.
- LL_DEBUGS("Avatar") << "ATT sending bake request for cof_version " << cof_version << LL_ENDL;
- mRetryPolicy->reset();
- sendRequest();
-}
-
-void RequestAgentUpdateAppearanceResponder::sendRequest()
-{
- if (gAgentAvatarp->isEditingAppearance())
- {
- // don't send out appearance updates if in appearance editing mode
- return;
- }
-
- if (!gAgent.getRegion())
- {
- LL_WARNS() << "Region not set, cannot request server appearance update" << LL_ENDL;
- return;
- }
- if (gAgent.getRegion()->getCentralBakeVersion()==0)
- {
- LL_WARNS() << "Region does not support baking" << LL_ENDL;
- }
- std::string url = gAgent.getRegion()->getCapability("UpdateAvatarAppearance");
- if (url.empty())
- {
- LL_WARNS() << "No cap for UpdateAvatarAppearance." << LL_ENDL;
- return;
- }
-
- LLSD body;
- S32 cof_version = LLAppearanceMgr::instance().getCOFVersion();
- if (gSavedSettings.getBOOL("DebugAvatarExperimentalServerAppearanceUpdate"))
- {
- body = LLAppearanceMgr::instance().dumpCOF();
- }
- else
- {
- body["cof_version"] = cof_version;
- if (gSavedSettings.getBOOL("DebugForceAppearanceRequestFailure"))
- {
- body["cof_version"] = cof_version+999;
- }
- }
- LL_DEBUGS("Avatar") << "request url " << url << " my_cof_version " << cof_version << LL_ENDL;
-
- mInFlightCounter++;
- mInFlightTimer.setTimerExpirySec(60.0);
- LLHTTPClient::post(url, body, this);
- llassert(cof_version >= gAgentAvatarp->mLastUpdateRequestCOFVersion);
- gAgentAvatarp->mLastUpdateRequestCOFVersion = cof_version;
-}
-
-void RequestAgentUpdateAppearanceResponder::debugCOF(const LLSD& content)
-{
- LL_INFOS("Avatar") << "AIS COF, version received: " << content["expected"].asInteger()
- << " ================================= " << LL_ENDL;
- std::set<LLUUID> ais_items, local_items;
- const LLSD& cof_raw = content["cof_raw"];
- for (LLSD::array_const_iterator it = cof_raw.beginArray();
- it != cof_raw.endArray(); ++it)
- {
- const LLSD& item = *it;
- if (item["parent_id"].asUUID() == LLAppearanceMgr::instance().getCOF())
- {
- ais_items.insert(item["item_id"].asUUID());
- if (item["type"].asInteger() == 24) // link
- {
- LL_INFOS("Avatar") << "AIS Link: item_id: " << item["item_id"].asUUID()
- << " linked_item_id: " << item["asset_id"].asUUID()
- << " name: " << item["name"].asString()
- << LL_ENDL;
- }
- else if (item["type"].asInteger() == 25) // folder link
- {
- LL_INFOS("Avatar") << "AIS Folder link: item_id: " << item["item_id"].asUUID()
- << " linked_item_id: " << item["asset_id"].asUUID()
- << " name: " << item["name"].asString()
- << LL_ENDL;
- }
- else
- {
- LL_INFOS("Avatar") << "AIS Other: item_id: " << item["item_id"].asUUID()
- << " linked_item_id: " << item["asset_id"].asUUID()
- << " name: " << item["name"].asString()
- << " type: " << item["type"].asInteger()
- << LL_ENDL;
- }
- }
- }
- LL_INFOS("Avatar") << LL_ENDL;
- LL_INFOS("Avatar") << "Local COF, version requested: " << content["observed"].asInteger()
- << " ================================= " << LL_ENDL;
- LLInventoryModel::cat_array_t cat_array;
- LLInventoryModel::item_array_t item_array;
- gInventory.collectDescendents(LLAppearanceMgr::instance().getCOF(),
- cat_array,item_array,LLInventoryModel::EXCLUDE_TRASH);
- for (S32 i=0; i<item_array.size(); i++)
- {
- const LLViewerInventoryItem* inv_item = item_array.at(i).get();
- local_items.insert(inv_item->getUUID());
- LL_INFOS("Avatar") << "LOCAL: item_id: " << inv_item->getUUID()
- << " linked_item_id: " << inv_item->getLinkedUUID()
- << " name: " << inv_item->getName()
- << " parent: " << inv_item->getParentUUID()
- << LL_ENDL;
- }
- LL_INFOS("Avatar") << " ================================= " << LL_ENDL;
- S32 local_only = 0, ais_only = 0;
- for (std::set<LLUUID>::iterator it = local_items.begin(); it != local_items.end(); ++it)
- {
- if (ais_items.find(*it) == ais_items.end())
- {
- LL_INFOS("Avatar") << "LOCAL ONLY: " << *it << LL_ENDL;
- local_only++;
- }
- }
- for (std::set<LLUUID>::iterator it = ais_items.begin(); it != ais_items.end(); ++it)
- {
- if (local_items.find(*it) == local_items.end())
- {
- LL_INFOS("Avatar") << "AIS ONLY: " << *it << LL_ENDL;
- ais_only++;
- }
- }
- if (local_only==0 && ais_only==0)
- {
- LL_INFOS("Avatar") << "COF contents identical, only version numbers differ (req "
- << content["observed"].asInteger()
- << " rcv " << content["expected"].asInteger()
- << ")" << LL_ENDL;
- }
-}
-
-/* virtual */ void RequestAgentUpdateAppearanceResponder::httpSuccess()
-{
- const LLSD& content = getContent();
- if (!content.isMap())
- {
- failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
- return;
- }
- if (content["success"].asBoolean())
- {
- LL_DEBUGS("Avatar") << "succeeded" << LL_ENDL;
- if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
- {
- dump_sequential_xml(gAgentAvatarp->getFullname() + "_appearance_request_ok", content);
- }
-
- onSuccess();
- }
- else
- {
- failureResult(HTTP_INTERNAL_ERROR, "Non-success response", content);
- }
-}
-
-void RequestAgentUpdateAppearanceResponder::onSuccess()
-{
- mInFlightCounter = llmax(mInFlightCounter-1,0);
-}
-
-/*virtual*/ void RequestAgentUpdateAppearanceResponder::httpFailure()
-{
- LL_WARNS("Avatar") << "appearance update request failed, status "
- << getStatus() << " reason " << getReason() << LL_ENDL;
-
- if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
- {
- const LLSD& content = getContent();
- dump_sequential_xml(gAgentAvatarp->getFullname() + "_appearance_request_error", content);
- debugCOF(content);
- }
- onFailure();
-}
-
-void RequestAgentUpdateAppearanceResponder::onFailure()
-{
- mInFlightCounter = llmax(mInFlightCounter-1,0);
-
- F32 seconds_to_wait;
- mRetryPolicy->onFailure(getStatus(), getResponseHeaders());
- if (mRetryPolicy->shouldRetry(seconds_to_wait))
- {
- LL_INFOS() << "retrying" << LL_ENDL;
- doAfterInterval(boost::bind(&RequestAgentUpdateAppearanceResponder::sendRequest,this),
- seconds_to_wait);
- }
- else
- {
- LL_WARNS() << "giving up after too many retries" << LL_ENDL;
- }
-}
-
LLSD LLAppearanceMgr::dumpCOF() const
{
@@ -3597,102 +3332,201 @@ LLSD LLAppearanceMgr::dumpCOF() const
void LLAppearanceMgr::requestServerAppearanceUpdate()
{
- mAppearanceResponder->onRequestRequested();
-}
-class LLIncrementCofVersionResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(LLIncrementCofVersionResponder);
-public:
- LLIncrementCofVersionResponder() : LLHTTPClient::Responder()
+ if (!testCOFRequestVersion())
{
- mRetryPolicy = new LLAdaptiveRetryPolicy(1.0, 16.0, 2.0, 5);
+ // *TODO: LL_LOG message here
+ return;
}
- virtual ~LLIncrementCofVersionResponder()
+ if ((mInFlightCounter > 0) && (mInFlightTimer.hasExpired()))
{
+ LL_WARNS("Avatar") << "in flight timer expired, resetting " << LL_ENDL;
+ mInFlightCounter = 0;
}
-protected:
- virtual void httpSuccess()
+ if (gAgentAvatarp->isEditingAppearance())
{
- LL_INFOS() << "Successfully incremented agent's COF." << LL_ENDL;
- const LLSD& content = getContent();
- if (!content.isMap())
- {
- failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
- return;
- }
- S32 new_version = content["category"]["version"].asInteger();
-
- // cof_version should have increased
- llassert(new_version > gAgentAvatarp->mLastUpdateRequestCOFVersion);
-
- gAgentAvatarp->mLastUpdateRequestCOFVersion = new_version;
+ LL_WARNS("Avatar") << "Avatar editing appearance, not sending request." << LL_ENDL;
+ // don't send out appearance updates if in appearance editing mode
+ return;
}
- virtual void httpFailure()
+ if (!gAgent.getRegion())
{
- LL_WARNS("Avatar") << "While attempting to increment the agent's cof we got an error "
- << dumpResponse() << LL_ENDL;
- F32 seconds_to_wait;
- mRetryPolicy->onFailure(getStatus(), getResponseHeaders());
- if (mRetryPolicy->shouldRetry(seconds_to_wait))
- {
- LL_INFOS() << "retrying" << LL_ENDL;
- doAfterInterval(boost::bind(&LLAppearanceMgr::incrementCofVersion,
- LLAppearanceMgr::getInstance(),
- LLHTTPClient::ResponderPtr(this)),
- seconds_to_wait);
- }
- else
- {
- LL_WARNS() << "giving up after too many retries" << LL_ENDL;
- }
+ LL_WARNS("Avatar") << "Region not set, cannot request server appearance update" << LL_ENDL;
+ return;
}
-
-private:
- LLPointer<LLHTTPRetryPolicy> mRetryPolicy;
-};
-
-void LLAppearanceMgr::incrementCofVersion(LLHTTPClient::ResponderPtr responder_ptr)
-{
- // If we don't have a region, report it as an error
- if (gAgent.getRegion() == NULL)
+ if (gAgent.getRegion()->getCentralBakeVersion() == 0)
{
- LL_WARNS() << "Region not set, cannot request cof_version increment" << LL_ENDL;
- return;
+ LL_WARNS("Avatar") << "Region does not support baking" << LL_ENDL;
}
- std::string url = gAgent.getRegion()->getCapability("IncrementCofVersion");
- if (url.empty())
+ LLSD postData;
+ S32 cof_version = LLAppearanceMgr::instance().getCOFVersion();
+ if (gSavedSettings.getBOOL("DebugAvatarExperimentalServerAppearanceUpdate"))
{
- LL_WARNS() << "No cap for IncrementCofVersion." << LL_ENDL;
- return;
+ postData = LLAppearanceMgr::instance().dumpCOF();
}
-
- LL_INFOS() << "Requesting cof_version be incremented via capability to: "
- << url << LL_ENDL;
- LLSD headers;
- LLSD body = LLSD::emptyMap();
-
- if (!responder_ptr.get())
+ else
{
- responder_ptr = LLHTTPClient::ResponderPtr(new LLIncrementCofVersionResponder());
+ postData["cof_version"] = cof_version;
+ if (gSavedSettings.getBOOL("DebugForceAppearanceRequestFailure"))
+ {
+ postData["cof_version"] = cof_version + 999;
+ }
}
- LLHTTPClient::get(url, body, responder_ptr, headers, 30.0f);
+ mInFlightCounter++;
+ mInFlightTimer.setTimerExpirySec(60.0);
+
+ llassert(cof_version >= gAgentAvatarp->mLastUpdateRequestCOFVersion);
+ gAgentAvatarp->mLastUpdateRequestCOFVersion = cof_version;
+
+ if (!gAgent.requestPostCapability("UpdateAvatarAppearance", postData,
+ static_cast<LLAgent::httpCallback_t>(boost::bind(&LLAppearanceMgr::serverAppearanceUpdateSuccess, this, _1)),
+ static_cast<LLAgent::httpCallback_t>(boost::bind(&LLAppearanceMgr::decrementInFlightCounter, this))))
+ {
+ LL_WARNS("Avatar") << "Unable to access UpdateAvatarAppearance in this region." << LL_ENDL;
+ }
}
-U32 LLAppearanceMgr::getNumAttachmentsInCOF()
+void LLAppearanceMgr::serverAppearanceUpdateSuccess(const LLSD &result)
{
- const LLUUID cof = getCOF();
- LLInventoryModel::item_array_t obj_items;
- getDescendentsOfAssetType(cof, obj_items, LLAssetType::AT_OBJECT);
- return obj_items.size();
+ decrementInFlightCounter();
+ if (result["success"].asBoolean())
+ {
+ LL_DEBUGS("Avatar") << "succeeded" << LL_ENDL;
+ if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
+ {
+ dump_sequential_xml(gAgentAvatarp->getFullname() + "_appearance_request_ok", result);
+ }
+ }
+ else
+ {
+ LL_WARNS("Avatar") << "Non success response for change appearance" << LL_ENDL;
+ if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
+ {
+ debugAppearanceUpdateCOF(result);
+ }
+ }
+}
+
+/*static*/
+void LLAppearanceMgr::debugAppearanceUpdateCOF(const LLSD& content)
+{
+ dump_sequential_xml(gAgentAvatarp->getFullname() + "_appearance_request_error", content);
+
+ LL_INFOS("Avatar") << "AIS COF, version received: " << content["expected"].asInteger()
+ << " ================================= " << LL_ENDL;
+ std::set<LLUUID> ais_items, local_items;
+ const LLSD& cof_raw = content["cof_raw"];
+ for (LLSD::array_const_iterator it = cof_raw.beginArray();
+ it != cof_raw.endArray(); ++it)
+ {
+ const LLSD& item = *it;
+ if (item["parent_id"].asUUID() == LLAppearanceMgr::instance().getCOF())
+ {
+ ais_items.insert(item["item_id"].asUUID());
+ if (item["type"].asInteger() == 24) // link
+ {
+ LL_INFOS("Avatar") << "AIS Link: item_id: " << item["item_id"].asUUID()
+ << " linked_item_id: " << item["asset_id"].asUUID()
+ << " name: " << item["name"].asString()
+ << LL_ENDL;
+ }
+ else if (item["type"].asInteger() == 25) // folder link
+ {
+ LL_INFOS("Avatar") << "AIS Folder link: item_id: " << item["item_id"].asUUID()
+ << " linked_item_id: " << item["asset_id"].asUUID()
+ << " name: " << item["name"].asString()
+ << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS("Avatar") << "AIS Other: item_id: " << item["item_id"].asUUID()
+ << " linked_item_id: " << item["asset_id"].asUUID()
+ << " name: " << item["name"].asString()
+ << " type: " << item["type"].asInteger()
+ << LL_ENDL;
+ }
+ }
+ }
+ LL_INFOS("Avatar") << LL_ENDL;
+ LL_INFOS("Avatar") << "Local COF, version requested: " << content["observed"].asInteger()
+ << " ================================= " << LL_ENDL;
+ LLInventoryModel::cat_array_t cat_array;
+ LLInventoryModel::item_array_t item_array;
+ gInventory.collectDescendents(LLAppearanceMgr::instance().getCOF(),
+ cat_array, item_array, LLInventoryModel::EXCLUDE_TRASH);
+ for (S32 i = 0; i < item_array.size(); i++)
+ {
+ const LLViewerInventoryItem* inv_item = item_array.at(i).get();
+ local_items.insert(inv_item->getUUID());
+ LL_INFOS("Avatar") << "LOCAL: item_id: " << inv_item->getUUID()
+ << " linked_item_id: " << inv_item->getLinkedUUID()
+ << " name: " << inv_item->getName()
+ << " parent: " << inv_item->getParentUUID()
+ << LL_ENDL;
+ }
+ LL_INFOS("Avatar") << " ================================= " << LL_ENDL;
+ S32 local_only = 0, ais_only = 0;
+ for (std::set<LLUUID>::iterator it = local_items.begin(); it != local_items.end(); ++it)
+ {
+ if (ais_items.find(*it) == ais_items.end())
+ {
+ LL_INFOS("Avatar") << "LOCAL ONLY: " << *it << LL_ENDL;
+ local_only++;
+ }
+ }
+ for (std::set<LLUUID>::iterator it = ais_items.begin(); it != ais_items.end(); ++it)
+ {
+ if (local_items.find(*it) == local_items.end())
+ {
+ LL_INFOS("Avatar") << "AIS ONLY: " << *it << LL_ENDL;
+ ais_only++;
+ }
+ }
+ if (local_only == 0 && ais_only == 0)
+ {
+ LL_INFOS("Avatar") << "COF contents identical, only version numbers differ (req "
+ << content["observed"].asInteger()
+ << " rcv " << content["expected"].asInteger()
+ << ")" << LL_ENDL;
+ }
}
+bool LLAppearanceMgr::testCOFRequestVersion() const
+{
+ // If we have already received an update for this or higher cof version, ignore.
+ S32 cof_version = getCOFVersion();
+ S32 last_rcv = gAgentAvatarp->mLastUpdateReceivedCOFVersion;
+ S32 last_req = gAgentAvatarp->mLastUpdateRequestCOFVersion;
+
+ LL_DEBUGS("Avatar") << "cof_version " << cof_version
+ << " last_rcv " << last_rcv
+ << " last_req " << last_req
+ << " in flight " << mInFlightCounter
+ << LL_ENDL;
+ if (cof_version < last_rcv)
+ {
+ LL_DEBUGS("Avatar") << "Have already received update for cof version " << last_rcv
+ << " will not request for " << cof_version << LL_ENDL;
+ return false;
+ }
+ if (/*mInFlightCounter > 0 &&*/ last_req >= cof_version)
+ {
+ LL_DEBUGS("Avatar") << "Request already in flight for cof version " << last_req
+ << " will not request for " << cof_version << LL_ENDL;
+ return false;
+ }
+
+ // Actually send the request.
+ LL_DEBUGS("Avatar") << "Will send request for cof_version " << cof_version << LL_ENDL;
+ return true;
+}
+
std::string LLAppearanceMgr::getAppearanceServiceURL() const
{
if (gSavedSettings.getString("DebugAvatarAppearanceServiceURLOverride").empty())
@@ -3961,15 +3795,17 @@ void LLAppearanceMgr::dumpItemArray(const LLInventoryModel::item_array_t& items,
}
}
+bool LLAppearanceMgr::mActive = true;
+
LLAppearanceMgr::LLAppearanceMgr():
mAttachmentInvLinkEnabled(false),
mOutfitIsDirty(false),
mOutfitLocked(false),
- mIsInUpdateAppearanceFromCOF(false),
- mAppearanceResponder(new RequestAgentUpdateAppearanceResponder)
+ mInFlightCounter(0),
+ mInFlightTimer(),
+ mIsInUpdateAppearanceFromCOF(false)
{
LLOutfitObserver& outfit_observer = LLOutfitObserver::instance();
-
// unlock outfit on save operation completed
outfit_observer.addCOFSavedCallback(boost::bind(
&LLAppearanceMgr::setOutfitLocked, this, false));
@@ -3977,11 +3813,12 @@ LLAppearanceMgr::LLAppearanceMgr():
mUnlockOutfitTimer.reset(new LLOutfitUnLockTimer(gSavedSettings.getS32(
"OutfitOperationsTimeout")));
- gIdleCallbacks.addFunction(&LLAttachmentsMgr::onIdle,NULL);
+ gIdleCallbacks.addFunction(&LLAttachmentsMgr::onIdle, NULL);
}
LLAppearanceMgr::~LLAppearanceMgr()
{
+ mActive = false;
}
void LLAppearanceMgr::setAttachmentInvLinkEnable(bool val)
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index 4ed8c1bfb9..9b6ceb7d3e 100755
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -34,12 +34,10 @@
#include "llinventorymodel.h"
#include "llinventoryobserver.h"
#include "llviewerinventory.h"
-#include "llhttpclient.h"
class LLWearableHoldingPattern;
class LLInventoryCallback;
class LLOutfitUnLockTimer;
-class RequestAgentUpdateAppearanceResponder;
class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
{
@@ -54,7 +52,6 @@ public:
void updateAppearanceFromCOF(bool enforce_item_restrictions = true,
bool enforce_ordering = true,
nullary_func_t post_update_func = no_op);
- bool needToSaveCOF();
void updateCOF(const LLUUID& category, bool append = false);
void wearInventoryCategory(LLInventoryCategory* category, bool copy, bool append);
void wearInventoryCategoryOnAvatar(LLInventoryCategory* category, bool append);
@@ -224,20 +221,23 @@ public:
void requestServerAppearanceUpdate();
- void incrementCofVersion(LLHTTPClient::ResponderPtr responder_ptr = NULL);
+ void setAppearanceServiceURL(const std::string& url) { mAppearanceServiceURL = url; }
+ std::string getAppearanceServiceURL() const;
- U32 getNumAttachmentsInCOF();
- // *HACK Remove this after server side texture baking is deployed on all sims.
- void incrementCofVersionLegacy();
+ bool testCOFRequestVersion() const;
+ void decrementInFlightCounter()
+ {
+ mInFlightCounter = llmax(mInFlightCounter - 1, 0);
+ }
- void setAppearanceServiceURL(const std::string& url) { mAppearanceServiceURL = url; }
- std::string getAppearanceServiceURL() const;
private:
+ void serverAppearanceUpdateSuccess(const LLSD &result);
+ static void debugAppearanceUpdateCOF(const LLSD& content);
+
std::string mAppearanceServiceURL;
-
protected:
LLAppearanceMgr();
~LLAppearanceMgr();
@@ -261,13 +261,14 @@ private:
bool mOutfitIsDirty;
bool mIsInUpdateAppearanceFromCOF; // to detect recursive calls.
- LLPointer<RequestAgentUpdateAppearanceResponder> mAppearanceResponder;
-
/**
* Lock for blocking operations on outfit until server reply or timeout exceed
* to avoid unsynchronized outfit state or performing duplicate operations.
*/
bool mOutfitLocked;
+ S32 mInFlightCounter;
+ LLTimer mInFlightTimer;
+ static bool mActive;
std::auto_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer;
diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp
index d2b1dcbf35..14020af166 100755
--- a/indra/newview/llassetuploadresponders.cpp
+++ b/indra/newview/llassetuploadresponders.cpp
@@ -352,6 +352,7 @@ void LLAssetUploadResponder::uploadComplete(const LLSD& content)
{
}
+#if 0
LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(
const LLSD& post_data,
const LLUUID& vfile_id,
@@ -473,7 +474,9 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content)
//LLImportColladaAssetCache::getInstance()->assetUploaded(mVFileID, content["new_asset"], TRUE);
}
+#endif
+#if 0
LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(
const LLSD& post_data,
const LLUUID& vfile_id,
@@ -580,7 +583,7 @@ void LLUpdateAgentInventoryResponder::uploadComplete(const LLSD& content)
break;
}
}
-
+#endif
LLUpdateTaskInventoryResponder::LLUpdateTaskInventoryResponder(const LLSD& post_data,
const LLUUID& vfile_id,
@@ -674,6 +677,7 @@ void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content)
}
+#if 0
/////////////////////////////////////////////////////
// LLNewAgentInventoryVariablePriceResponder::Impl //
/////////////////////////////////////////////////////
@@ -1144,5 +1148,5 @@ void LLNewAgentInventoryVariablePriceResponder::showConfirmationDialog(
LLPointer<LLNewAgentInventoryVariablePriceResponder>(this)));
}
}
-
+#endif
diff --git a/indra/newview/llassetuploadresponders.h b/indra/newview/llassetuploadresponders.h
index 7fbebc7481..71995873fa 100755
--- a/indra/newview/llassetuploadresponders.h
+++ b/indra/newview/llassetuploadresponders.h
@@ -60,6 +60,7 @@ protected:
std::string mFileName;
};
+#if 0
// TODO*: Remove this once deprecated
class LLNewAgentInventoryResponder : public LLAssetUploadResponder
{
@@ -78,7 +79,8 @@ public:
protected:
virtual void httpFailure();
};
-
+#endif
+#if 0
// A base class which goes through and performs some default
// actions for variable price uploads. If more specific actions
// are needed (such as different confirmation messages, etc.)
@@ -115,7 +117,9 @@ private:
class Impl;
Impl* mImpl;
};
+#endif
+#if 0
class LLUpdateAgentInventoryResponder : public LLAssetUploadResponder
{
public:
@@ -127,6 +131,7 @@ public:
LLAssetType::EType asset_type);
virtual void uploadComplete(const LLSD& content);
};
+#endif
class LLUpdateTaskInventoryResponder : public LLAssetUploadResponder
{
diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp
index 38e153137c..e260142254 100644
--- a/indra/newview/llavatarrenderinfoaccountant.cpp
+++ b/indra/newview/llavatarrenderinfoaccountant.cpp
@@ -35,7 +35,6 @@
// external library headers
// other Linden headers
#include "llcharacter.h"
-#include "llhttpclient.h"
#include "lltimer.h"
#include "llviewercontrol.h"
#include "llviewermenu.h"
@@ -43,7 +42,10 @@
#include "llviewerregion.h"
#include "llvoavatar.h"
#include "llworld.h"
-
+#include "llhttpsdhandler.h"
+#include "httpheaders.h"
+#include "httpoptions.h"
+#include "llcorehttputil.h"
static const std::string KEY_AGENTS = "agents"; // map
static const std::string KEY_WEIGHT = "weight"; // integer
@@ -55,166 +57,178 @@ static const std::string KEY_ERROR = "error";
// Send data updates about once per minute, only need per-frame resolution
LLFrameTimer LLAvatarRenderInfoAccountant::sRenderInfoReportTimer;
+//LLCore::HttpRequest::ptr_t LLAvatarRenderInfoAccountant::sHttpRequest;
-
-// HTTP responder class for GET request for avatar render weight information
-class LLAvatarRenderInfoGetResponder : public LLHTTPClient::Responder
+//=========================================================================
+void LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro(std::string url, U64 regionHandle)
{
-public:
- LLAvatarRenderInfoGetResponder(U64 region_handle) : mRegionHandle(region_handle)
- {
- }
-
- virtual void error(U32 statusNum, const std::string& reason)
- {
- LLViewerRegion * regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
- if (regionp)
- {
- LL_WARNS() << "HTTP error result for avatar weight GET: " << statusNum
- << ", " << reason
- << " returned by region " << regionp->getName()
- << LL_ENDL;
- }
- else
- {
- LL_WARNS() << "Avatar render weight GET error recieved but region not found for "
- << mRegionHandle
- << ", error " << statusNum
- << ", " << reason
- << LL_ENDL;
- }
-
- }
-
- virtual void result(const LLSD& content)
- {
- LLViewerRegion * regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
- if (regionp)
- {
- if (LLAvatarRenderInfoAccountant::logRenderInfo())
- {
- LL_INFOS() << "LRI: Result for avatar weights request for region " << regionp->getName() << ":" << LL_ENDL;
- }
-
- if (content.isMap())
- {
- if (content.has(KEY_AGENTS))
- {
- const LLSD & agents = content[KEY_AGENTS];
- if (agents.isMap())
- {
- LLSD::map_const_iterator report_iter = agents.beginMap();
- while (report_iter != agents.endMap())
- {
- LLUUID target_agent_id = LLUUID(report_iter->first);
- const LLSD & agent_info_map = report_iter->second;
- LLViewerObject* avatarp = gObjectList.findObject(target_agent_id);
- if (avatarp &&
- avatarp->isAvatar() &&
- agent_info_map.isMap())
- { // Extract the data for this avatar
-
- if (LLAvatarRenderInfoAccountant::logRenderInfo())
- {
- LL_INFOS() << "LRI: Agent " << target_agent_id
- << ": " << agent_info_map << LL_ENDL;
- }
-
- if (agent_info_map.has(KEY_WEIGHT))
- {
- ((LLVOAvatar *) avatarp)->setReportedVisualComplexity(agent_info_map[KEY_WEIGHT].asInteger());
- }
- }
- report_iter++;
- }
- }
- } // has "agents"
- else if (content.has(KEY_ERROR))
- {
- const LLSD & error = content[KEY_ERROR];
- LL_WARNS() << "Avatar render info GET error: "
- << error[KEY_IDENTIFIER]
- << ": " << error[KEY_MESSAGE]
- << " from region " << regionp->getName()
- << LL_ENDL;
- }
- }
- }
- else
- {
- LL_INFOS() << "Avatar render weight info recieved but region not found for "
- << mRegionHandle << LL_ENDL;
- }
- }
-
-private:
- U64 mRegionHandle;
-};
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("AvatarRenderInfoAccountant", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+ LLViewerRegion * regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+ if (!regionp)
+ {
+ LL_WARNS("AvatarRenderInfoAccountant") << "Avatar render weight info received but region not found for "
+ << regionHandle << LL_ENDL;
+ return;
+ }
+
+ LLSD httpResults = result["http_result"];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS("AvatarRenderInfoAccountant") << "HTTP status, " << status.toTerseString() << LL_ENDL;
+ return;
+ }
+
+ if (result.has(KEY_AGENTS))
+ {
+ const LLSD & agents = result[KEY_AGENTS];
+ if (agents.isMap())
+ {
+ LLSD::map_const_iterator report_iter = agents.beginMap();
+ while (report_iter != agents.endMap())
+ {
+ LLUUID target_agent_id = LLUUID(report_iter->first);
+ const LLSD & agent_info_map = report_iter->second;
+ LLViewerObject* avatarp = gObjectList.findObject(target_agent_id);
+ if (avatarp &&
+ avatarp->isAvatar() &&
+ agent_info_map.isMap())
+ { // Extract the data for this avatar
+
+ if (LLAvatarRenderInfoAccountant::logRenderInfo())
+ {
+ LL_INFOS() << "LRI: Agent " << target_agent_id
+ << ": " << agent_info_map << LL_ENDL;
+ }
+
+ if (agent_info_map.has(KEY_WEIGHT))
+ {
+ ((LLVOAvatar *) avatarp)->setReportedVisualComplexity(agent_info_map[KEY_WEIGHT].asInteger());
+ }
+ }
+ report_iter++;
+ }
+ }
+ } // has "agents"
+ else if (result.has(KEY_ERROR))
+ {
+ const LLSD & error = result[KEY_ERROR];
+ LL_WARNS() << "Avatar render info GET error: "
+ << error[KEY_IDENTIFIER]
+ << ": " << error[KEY_MESSAGE]
+ << " from region " << regionp->getName()
+ << LL_ENDL;
+ }
+}
-// HTTP responder class for POST request for avatar render weight information
-class LLAvatarRenderInfoPostResponder : public LLHTTPClient::Responder
+//-------------------------------------------------------------------------
+void LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro(std::string url, U64 regionHandle)
{
-public:
- LLAvatarRenderInfoPostResponder(U64 region_handle) : mRegionHandle(region_handle)
- {
- }
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("AvatarRenderInfoAccountant", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLViewerRegion * regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+ if (!regionp)
+ {
+ LL_WARNS("AvatarRenderInfoAccountant") << "Avatar render weight calculation but region not found for "
+ << regionHandle << LL_ENDL;
+ return;
+ }
+
+ if (logRenderInfo())
+ {
+ LL_INFOS("AvatarRenderInfoAccountant") << "LRI: Sending avatar render info to region " << regionp->getName()
+ << " from " << url << LL_ENDL;
+ }
+
+ // Build the render info to POST to the region
+ LLSD report = LLSD::emptyMap();
+ LLSD agents = LLSD::emptyMap();
+
+ std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
+ while( iter != LLCharacter::sInstances.end() )
+ {
+ LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*iter);
+ if (avatar &&
+ avatar->getRezzedStatus() >= 2 && // Mostly rezzed (maybe without baked textures downloaded)
+ !avatar->isDead() && // Not dead yet
+ avatar->getObjectHost() == regionp->getHost()) // Ensure it's on the same region
+ {
+ avatar->calculateUpdateRenderCost(); // Make sure the numbers are up-to-date
+
+ LLSD info = LLSD::emptyMap();
+ if (avatar->getVisualComplexity() > 0)
+ {
+ info[KEY_WEIGHT] = avatar->getVisualComplexity();
+ agents[avatar->getID().asString()] = info;
+
+ if (logRenderInfo())
+ {
+ LL_INFOS("AvatarRenderInfoAccountant") << "LRI: Sending avatar render info for " << avatar->getID()
+ << ": " << info << LL_ENDL;
+ LL_INFOS("AvatarRenderInfoAccountant") << "LRI: other info geometry " << avatar->getAttachmentGeometryBytes()
+ << ", area " << avatar->getAttachmentSurfaceArea()
+ << LL_ENDL;
+ }
+ }
+ }
+ iter++;
+ }
+
+ if (agents.size() == 0)
+ return;
+
+ report[KEY_AGENTS] = agents;
+ regionp = NULL;
+ LLSD result = httpAdapter->postAndYield(httpRequest, url, report);
+
+ regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+ if (!regionp)
+ {
+ LL_INFOS("AvatarRenderInfoAccountant") << "Avatar render weight POST result received but region not found for "
+ << regionHandle << LL_ENDL;
+ return;
+ }
+
+ LLSD httpResults = result["http_result"];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+ if (!status)
+ {
+ LL_WARNS("AvatarRenderInfoAccountant") << "HTTP status, " << status.toTerseString() << LL_ENDL;
+ return;
+ }
+
+ if (LLAvatarRenderInfoAccountant::logRenderInfo())
+ {
+ LL_INFOS("AvatarRenderInfoAccountant") << "LRI: Result for avatar weights POST for region " << regionp->getName()
+ << ": " << result << LL_ENDL;
+ }
+
+ if (result.isMap())
+ {
+ if (result.has(KEY_ERROR))
+ {
+ const LLSD & error = result[KEY_ERROR];
+ LL_WARNS("AvatarRenderInfoAccountant") << "Avatar render info POST error: "
+ << error[KEY_IDENTIFIER]
+ << ": " << error[KEY_MESSAGE]
+ << " from region " << regionp->getName()
+ << LL_ENDL;
+ }
+ }
- virtual void error(U32 statusNum, const std::string& reason)
- {
- LLViewerRegion * regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
- if (regionp)
- {
- LL_WARNS() << "HTTP error result for avatar weight POST: " << statusNum
- << ", " << reason
- << " returned by region " << regionp->getName()
- << LL_ENDL;
- }
- else
- {
- LL_WARNS() << "Avatar render weight POST error recieved but region not found for "
- << mRegionHandle
- << ", error " << statusNum
- << ", " << reason
- << LL_ENDL;
- }
- }
-
- virtual void result(const LLSD& content)
- {
- LLViewerRegion * regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
- if (regionp)
- {
- if (LLAvatarRenderInfoAccountant::logRenderInfo())
- {
- LL_INFOS() << "LRI: Result for avatar weights POST for region " << regionp->getName()
- << ": " << content << LL_ENDL;
- }
-
- if (content.isMap())
- {
- if (content.has(KEY_ERROR))
- {
- const LLSD & error = content[KEY_ERROR];
- LL_WARNS() << "Avatar render info POST error: "
- << error[KEY_IDENTIFIER]
- << ": " << error[KEY_MESSAGE]
- << " from region " << regionp->getName()
- << LL_ENDL;
- }
- }
- }
- else
- {
- LL_INFOS() << "Avatar render weight POST result recieved but region not found for "
- << mRegionHandle << LL_ENDL;
- }
- }
-
-private:
- U64 mRegionHandle;
-};
+}
// static
// Send request for one region, no timer checks
@@ -223,53 +237,9 @@ void LLAvatarRenderInfoAccountant::sendRenderInfoToRegion(LLViewerRegion * regio
std::string url = regionp->getCapability("AvatarRenderInfo");
if (!url.empty())
{
- if (logRenderInfo())
- {
- LL_INFOS() << "LRI: Sending avatar render info to region "
- << regionp->getName()
- << " from " << url
- << LL_ENDL;
- }
-
- // Build the render info to POST to the region
- LLSD report = LLSD::emptyMap();
- LLSD agents = LLSD::emptyMap();
-
- std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
- while( iter != LLCharacter::sInstances.end() )
- {
- LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*iter);
- if (avatar &&
- avatar->getRezzedStatus() >= 2 && // Mostly rezzed (maybe without baked textures downloaded)
- !avatar->isDead() && // Not dead yet
- avatar->getObjectHost() == regionp->getHost()) // Ensure it's on the same region
- {
- avatar->calculateUpdateRenderCost(); // Make sure the numbers are up-to-date
-
- LLSD info = LLSD::emptyMap();
- if (avatar->getVisualComplexity() > 0)
- {
- info[KEY_WEIGHT] = avatar->getVisualComplexity();
- agents[avatar->getID().asString()] = info;
-
- if (logRenderInfo())
- {
- LL_INFOS() << "LRI: Sending avatar render info for " << avatar->getID()
- << ": " << info << LL_ENDL;
- LL_INFOS() << "LRI: other info geometry " << avatar->getAttachmentGeometryBytes()
- << ", area " << avatar->getAttachmentSurfaceArea()
- << LL_ENDL;
- }
- }
- }
- iter++;
- }
-
- report[KEY_AGENTS] = agents;
- if (agents.size() > 0)
- {
- LLHTTPClient::post(url, report, new LLAvatarRenderInfoPostResponder(regionp->getHandle()));
- }
+ std::string coroname =
+ LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro",
+ boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro, url, regionp->getHandle()));
}
}
@@ -292,7 +262,9 @@ void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regi
}
// First send a request to get the latest data
- LLHTTPClient::get(url, new LLAvatarRenderInfoGetResponder(regionp->getHandle()));
+ std::string coroname =
+ LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro",
+ boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro, url, regionp->getHandle()));
}
}
@@ -301,6 +273,9 @@ void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regi
// Called every frame - send render weight requests to every region
void LLAvatarRenderInfoAccountant::idle()
{
+// if (!LLAvatarRenderInfoAccountant::sHttpRequest)
+// sHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest());
+
if (sRenderInfoReportTimer.hasExpired())
{
const F32 SECS_BETWEEN_REGION_SCANS = 5.f; // Scan the region list every 5 seconds
@@ -393,6 +368,7 @@ void LLAvatarRenderInfoAccountant::expireRenderInfoReportTimer(const LLUUID& reg
// static
bool LLAvatarRenderInfoAccountant::logRenderInfo()
{
- static LLCachedControl<bool> render_mute_logging_enabled(gSavedSettings, "RenderAutoMuteLogging", false);
- return render_mute_logging_enabled;
+ return true;
+// static LLCachedControl<bool> render_mute_logging_enabled(gSavedSettings, "RenderAutoMuteLogging", false);
+// return render_mute_logging_enabled;
}
diff --git a/indra/newview/llavatarrenderinfoaccountant.h b/indra/newview/llavatarrenderinfoaccountant.h
index d68f2dccfb..f7a04cca2c 100644
--- a/indra/newview/llavatarrenderinfoaccountant.h
+++ b/indra/newview/llavatarrenderinfoaccountant.h
@@ -29,6 +29,9 @@
#if ! defined(LL_llavatarrenderinfoaccountant_H)
#define LL_llavatarrenderinfoaccountant_H
+#include "httpcommon.h"
+#include "llcoros.h"
+
class LLViewerRegion;
// Class to gather avatar rendering information
@@ -36,8 +39,6 @@ class LLViewerRegion;
class LLAvatarRenderInfoAccountant
{
public:
- LLAvatarRenderInfoAccountant() {};
- ~LLAvatarRenderInfoAccountant() {};
static void sendRenderInfoToRegion(LLViewerRegion * regionp);
static void getRenderInfoFromRegion(LLViewerRegion * regionp);
@@ -49,8 +50,16 @@ public:
static bool logRenderInfo();
private:
+ LLAvatarRenderInfoAccountant() {};
+ ~LLAvatarRenderInfoAccountant() {};
+
// Send data updates about once per minute, only need per-frame resolution
static LLFrameTimer sRenderInfoReportTimer;
+
+ static void avatarRenderInfoGetCoro(std::string url, U64 regionHandle);
+ static void avatarRenderInfoReportCoro(std::string url, U64 regionHandle);
+
+
};
#endif /* ! defined(LL_llavatarrenderinfoaccountant_H) */
diff --git a/indra/newview/llcapabilitylistener.cpp b/indra/newview/llcapabilitylistener.cpp
deleted file mode 100755
index ef9b910ae5..0000000000
--- a/indra/newview/llcapabilitylistener.cpp
+++ /dev/null
@@ -1,202 +0,0 @@
-/**
- * @file llcapabilitylistener.cpp
- * @author Nat Goodspeed
- * @date 2009-01-07
- * @brief Implementation for llcapabilitylistener.
- *
- * $LicenseInfo:firstyear=2009&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$
- */
-
-// Precompiled header
-#include "llviewerprecompiledheaders.h"
-// associated header
-#include "llcapabilitylistener.h"
-// STL headers
-#include <map>
-// std headers
-// external library headers
-#include <boost/bind.hpp>
-// other Linden headers
-#include "stringize.h"
-#include "llcapabilityprovider.h"
-#include "message.h"
-
-class LLCapabilityListener::CapabilityMappers: public LLSingleton<LLCapabilityListener::CapabilityMappers>
-{
-public:
- void registerMapper(const LLCapabilityListener::CapabilityMapper*);
- void unregisterMapper(const LLCapabilityListener::CapabilityMapper*);
- const LLCapabilityListener::CapabilityMapper* find(const std::string& cap) const;
-
- struct DupCapMapper: public std::runtime_error
- {
- DupCapMapper(const std::string& what):
- std::runtime_error(std::string("DupCapMapper: ") + what)
- {}
- };
-
-private:
- friend class LLSingleton<LLCapabilityListener::CapabilityMappers>;
- CapabilityMappers();
-
- typedef std::map<std::string, const LLCapabilityListener::CapabilityMapper*> CapabilityMap;
- CapabilityMap mMap;
-};
-
-LLCapabilityListener::LLCapabilityListener(const std::string& name,
- LLMessageSystem* messageSystem,
- const LLCapabilityProvider& provider,
- const LLUUID& agentID,
- const LLUUID& sessionID):
- mEventPump(name),
- mMessageSystem(messageSystem),
- mProvider(provider),
- mAgentID(agentID),
- mSessionID(sessionID)
-{
- mEventPump.listen("self", boost::bind(&LLCapabilityListener::capListener, this, _1));
-}
-
-bool LLCapabilityListener::capListener(const LLSD& request)
-{
- // Extract what we want from the request object. We do it all up front
- // partly to document what we expect.
- LLSD::String cap(request["message"]);
- LLSD payload(request["payload"]);
- LLSD::String reply(request["reply"]);
- LLSD::String error(request["error"]);
- LLSD::Real timeout(request["timeout"]);
- // If the LLSD doesn't even have a "message" key, we doubt it was intended
- // for this listener.
- if (cap.empty())
- {
- LL_ERRS("capListener") << "capability request event without 'message' key to '"
- << getCapAPI().getName()
- << "' on region\n" << mProvider.getDescription()
- << LL_ENDL;
- return false; // in case fatal-error function isn't
- }
- // Establish default timeout. This test relies on LLSD::asReal() returning
- // exactly 0.0 for an undef value.
- if (! timeout)
- {
- timeout = HTTP_REQUEST_EXPIRY_SECS;
- }
- // Look up the url for the requested capability name.
- std::string url = mProvider.getCapability(cap);
- if (! url.empty())
- {
- // This capability is supported by the region to which we're talking.
- LLHTTPClient::post(url, payload,
- new LLSDMessage::EventResponder(LLEventPumps::instance(),
- request,
- mProvider.getDescription(),
- cap, reply, error),
- LLSD(), // headers
- timeout);
- }
- else
- {
- // Capability not supported -- do we have a registered mapper?
- const CapabilityMapper* mapper = CapabilityMappers::instance().find(cap);
- if (! mapper) // capability neither supported nor mapped
- {
- LL_ERRS("capListener") << "unsupported capability '" << cap << "' request to '"
- << getCapAPI().getName() << "' on region\n"
- << mProvider.getDescription()
- << LL_ENDL;
- }
- else if (! mapper->getReplyName().empty()) // mapper expects reply support
- {
- LL_ERRS("capListener") << "Mapper for capability '" << cap
- << "' requires unimplemented support for reply message '"
- << mapper->getReplyName()
- << "' on '" << getCapAPI().getName() << "' on region\n"
- << mProvider.getDescription()
- << LL_ENDL;
- }
- else
- {
- LL_INFOS("capListener") << "fallback invoked for capability '" << cap
- << "' request to '" << getCapAPI().getName()
- << "' on region\n" << mProvider.getDescription()
- << LL_ENDL;
- mapper->buildMessage(mMessageSystem, mAgentID, mSessionID, cap, payload);
- mMessageSystem->sendReliable(mProvider.getHost());
- }
- }
- return false;
-}
-
-LLCapabilityListener::CapabilityMapper::CapabilityMapper(const std::string& cap, const std::string& reply):
- mCapName(cap),
- mReplyName(reply)
-{
- LLCapabilityListener::CapabilityMappers::instance().registerMapper(this);
-}
-
-LLCapabilityListener::CapabilityMapper::~CapabilityMapper()
-{
- LLCapabilityListener::CapabilityMappers::instance().unregisterMapper(this);
-}
-
-LLSD LLCapabilityListener::CapabilityMapper::readResponse(LLMessageSystem* messageSystem) const
-{
- return LLSD();
-}
-
-LLCapabilityListener::CapabilityMappers::CapabilityMappers() {}
-
-void LLCapabilityListener::CapabilityMappers::registerMapper(const LLCapabilityListener::CapabilityMapper* mapper)
-{
- // Try to insert a new map entry by which we can look up the passed mapper
- // instance.
- std::pair<CapabilityMap::iterator, bool> inserted =
- mMap.insert(CapabilityMap::value_type(mapper->getCapName(), mapper));
- // If we already have a mapper for that name, insert() merely located the
- // existing iterator and returned false. It is a coding error to try to
- // register more than one mapper for the same capability name.
- if (! inserted.second)
- {
- throw DupCapMapper(std::string("Duplicate capability name ") + mapper->getCapName());
- }
-}
-
-void LLCapabilityListener::CapabilityMappers::unregisterMapper(const LLCapabilityListener::CapabilityMapper* mapper)
-{
- CapabilityMap::iterator found = mMap.find(mapper->getCapName());
- if (found != mMap.end())
- {
- mMap.erase(found);
- }
-}
-
-const LLCapabilityListener::CapabilityMapper*
-LLCapabilityListener::CapabilityMappers::find(const std::string& cap) const
-{
- CapabilityMap::const_iterator found = mMap.find(cap);
- if (found != mMap.end())
- {
- return found->second;
- }
- return NULL;
-}
diff --git a/indra/newview/llcapabilitylistener.h b/indra/newview/llcapabilitylistener.h
deleted file mode 100755
index e7535013e7..0000000000
--- a/indra/newview/llcapabilitylistener.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/**
- * @file llcapabilitylistener.h
- * @author Nat Goodspeed
- * @date 2009-01-07
- * @brief Provide an event-based API for capability requests
- *
- * $LicenseInfo:firstyear=2009&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$
- */
-
-#if ! defined(LL_LLCAPABILITYLISTENER_H)
-#define LL_LLCAPABILITYLISTENER_H
-
-#include "llevents.h" // LLEventPump
-#include "llsdmessage.h" // LLSDMessage::ArgError
-#include "llerror.h" // LOG_CLASS()
-
-class LLCapabilityProvider;
-class LLMessageSystem;
-class LLSD;
-
-class LLCapabilityListener
-{
- LOG_CLASS(LLCapabilityListener);
-public:
- LLCapabilityListener(const std::string& name, LLMessageSystem* messageSystem,
- const LLCapabilityProvider& provider,
- const LLUUID& agentID, const LLUUID& sessionID);
-
- /// Capability-request exception
- typedef LLSDMessage::ArgError ArgError;
- /// Get LLEventPump on which we listen for capability requests
- /// (https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes#Capabilities)
- LLEventPump& getCapAPI() { return mEventPump; }
-
- /**
- * Base class for mapping an as-yet-undeployed capability name to a (pair
- * of) LLMessageSystem message(s). To map a capability name to such
- * messages, derive a subclass of CapabilityMapper and declare a static
- * instance in a translation unit known to be loaded. The mapping is not
- * region-specific. If an LLViewerRegion's capListener() receives a
- * request for a supported capability, it will use the capability's URL.
- * If not, it will look for an applicable CapabilityMapper subclass
- * instance.
- */
- class CapabilityMapper
- {
- public:
- /**
- * Base-class constructor. Typically your subclass constructor will
- * pass these parameters as literals.
- * @param cap the capability name handled by this (subclass) instance
- * @param reply the name of the response LLMessageSystem message. Omit
- * if the LLMessageSystem message you intend to send doesn't prompt a
- * reply message, or if you already handle that message in some other
- * way.
- */
- CapabilityMapper(const std::string& cap, const std::string& reply = "");
- virtual ~CapabilityMapper();
- /// query the capability name
- std::string getCapName() const { return mCapName; }
- /// query the reply message name
- std::string getReplyName() const { return mReplyName; }
- /**
- * Override this method to build the LLMessageSystem message we should
- * send instead of the requested capability message. DO NOT send that
- * message: that will be handled by the caller.
- */
- virtual void buildMessage(LLMessageSystem* messageSystem,
- const LLUUID& agentID,
- const LLUUID& sessionID,
- const std::string& capabilityName,
- const LLSD& payload) const = 0;
- /**
- * Override this method if you pass a non-empty @a reply
- * LLMessageSystem message name to the constructor: that is, if you
- * expect to receive an LLMessageSystem message in response to the
- * message you constructed in buildMessage(). If you don't pass a @a
- * reply message name, you need not override this method as it won't
- * be called.
- *
- * Using LLMessageSystem message-reading operations, your
- * readResponse() override should construct and return an LLSD object
- * of the form you expect to receive from the real implementation of
- * the capability you intend to invoke, when it finally goes live.
- */
- virtual LLSD readResponse(LLMessageSystem* messageSystem) const;
-
- private:
- const std::string mCapName;
- const std::string mReplyName;
- };
-
-private:
- /// Bind the LLCapabilityProvider passed to our ctor
- const LLCapabilityProvider& mProvider;
-
- /// Post an event to this LLEventPump to invoke a capability message on
- /// the bound LLCapabilityProvider's server
- /// (https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes#Capabilities)
- LLEventStream mEventPump;
-
- LLMessageSystem* mMessageSystem;
- LLUUID mAgentID, mSessionID;
-
- /// listener to process capability requests
- bool capListener(const LLSD&);
-
- /// helper class for capListener()
- class CapabilityMappers;
-};
-
-#endif /* ! defined(LL_LLCAPABILITYLISTENER_H) */
diff --git a/indra/newview/llclassifiedstatsresponder.cpp b/indra/newview/llclassifiedstatsresponder.cpp
deleted file mode 100755
index f1ef8e9a03..0000000000
--- a/indra/newview/llclassifiedstatsresponder.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * @file llclassifiedstatsresponder.cpp
- * @brief Receives information about classified ad click-through
- * counts for display in the classified information UI.
- *
- * $LicenseInfo:firstyear=2007&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 "llviewerprecompiledheaders.h"
-
-#include "llclassifiedstatsresponder.h"
-
-#include "llpanelclassified.h"
-#include "llpanel.h"
-#include "llhttpclient.h"
-#include "llsdserialize.h"
-#include "llviewerregion.h"
-#include "llview.h"
-#include "message.h"
-
-LLClassifiedStatsResponder::LLClassifiedStatsResponder(LLUUID classified_id)
-: mClassifiedID(classified_id)
-{}
-
-/*virtual*/
-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();
- S32 search_teleport = content["search_teleport_clicks"].asInteger();
- S32 search_map = content["search_map_clicks"].asInteger();
- S32 search_profile = content["search_profile_clicks"].asInteger();
-
- LLPanelClassifiedInfo::setClickThrough( mClassifiedID,
- teleport + search_teleport,
- map + search_map,
- profile + search_profile,
- true);
-}
-
-/*virtual*/
-void LLClassifiedStatsResponder::httpFailure()
-{
- LL_WARNS() << dumpResponse() << LL_ENDL;
-}
-
diff --git a/indra/newview/llclassifiedstatsresponder.h b/indra/newview/llclassifiedstatsresponder.h
deleted file mode 100755
index efa4d82411..0000000000
--- a/indra/newview/llclassifiedstatsresponder.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * @file llclassifiedstatsresponder.h
- * @brief Receives information about classified ad click-through
- * counts for display in the classified information UI.
- *
- * $LicenseInfo:firstyear=2007&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_LLCLASSIFIEDSTATSRESPONDER_H
-#define LL_LLCLASSIFIEDSTATSRESPONDER_H
-
-#include "llhttpclient.h"
-#include "llview.h"
-#include "lluuid.h"
-
-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 httpSuccess();
- //If we get back an error (not found, etc...), handle it here
- virtual void httpFailure();
-
-protected:
- LLUUID mClassifiedID;
-};
-
-#endif // LL_LLCLASSIFIEDSTATSRESPONDER_H
diff --git a/indra/newview/llcoproceduremanager.cpp b/indra/newview/llcoproceduremanager.cpp
new file mode 100644
index 0000000000..d3168985f8
--- /dev/null
+++ b/indra/newview/llcoproceduremanager.cpp
@@ -0,0 +1,176 @@
+/**
+* @file llcoproceduremanager.cpp
+* @author Rider Linden
+* @brief Singleton class for managing asset uploads to the sim.
+*
+* $LicenseInfo:firstyear=2015&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2015, 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 "llviewerprecompiledheaders.h"
+#include "linden_common.h"
+
+#include "llviewercontrol.h"
+
+#include "llcoproceduremanager.h"
+
+//=========================================================================
+#define COROCOUNT 1
+
+//=========================================================================
+LLCoprocedureManager::LLCoprocedureManager():
+ LLSingleton<LLCoprocedureManager>(),
+ mPendingCoprocs(),
+ mShutdown(false),
+ mWakeupTrigger("CoprocedureManager", true),
+ mCoroMapping(),
+ mHTTPPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID)
+{
+
+ // *TODO: Retrieve the actual number of concurrent coroutines fro gSavedSettings and
+ // clamp to a "reasonable" number.
+ for (int count = 0; count < COROCOUNT; ++count)
+ {
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter =
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t(
+ new LLCoreHttpUtil::HttpCoroutineAdapter("uploadPostAdapter", mHTTPPolicy));
+
+ std::string uploadCoro = LLCoros::instance().launch("LLCoprocedureManager::coprocedureInvokerCoro",
+ boost::bind(&LLCoprocedureManager::coprocedureInvokerCoro, this, httpAdapter));
+
+ mCoroMapping.insert(CoroAdapterMap_t::value_type(uploadCoro, httpAdapter));
+ }
+
+ mWakeupTrigger.post(LLSD());
+}
+
+LLCoprocedureManager::~LLCoprocedureManager()
+{
+ shutdown();
+}
+
+//=========================================================================
+
+void LLCoprocedureManager::shutdown(bool hardShutdown)
+{
+ CoroAdapterMap_t::iterator it;
+
+ for (it = mCoroMapping.begin(); it != mCoroMapping.end(); ++it)
+ {
+ if (!(*it).first.empty())
+ {
+ if (hardShutdown)
+ {
+ LLCoros::instance().kill((*it).first);
+ }
+ }
+ if ((*it).second)
+ {
+ (*it).second->cancelYieldingOperation();
+ }
+ }
+
+ mShutdown = true;
+ mCoroMapping.clear();
+ mPendingCoprocs.clear();
+}
+
+//=========================================================================
+LLUUID LLCoprocedureManager::enqueueCoprocedure(const std::string &name, LLCoprocedureManager::CoProcedure_t proc)
+{
+ LLUUID id(LLUUID::generateNewID());
+
+ mPendingCoprocs.push_back(QueuedCoproc::ptr_t(new QueuedCoproc(name, id, proc)));
+ LL_INFOS() << "Coprocedure(" << name << ") enqueued with id=" << id.asString() << LL_ENDL;
+
+ mWakeupTrigger.post(LLSD());
+
+ return id;
+}
+
+void LLCoprocedureManager::cancelCoprocedure(const LLUUID &id)
+{
+ // first check the active coroutines. If there, remove it and return.
+ ActiveCoproc_t::iterator itActive = mActiveCoprocs.find(id);
+ if (itActive != mActiveCoprocs.end())
+ {
+ LL_INFOS() << "Found and canceling active coprocedure with id=" << id.asString() << LL_ENDL;
+ (*itActive).second->cancelYieldingOperation();
+ mActiveCoprocs.erase(itActive);
+ return;
+ }
+
+ for (CoprocQueue_t::iterator it = mPendingCoprocs.begin(); it != mPendingCoprocs.end(); ++it)
+ {
+ if ((*it)->mId == id)
+ {
+ LL_INFOS() << "Found and removing queued coroutine(" << (*it)->mName << ") with Id=" << id.asString() << LL_ENDL;
+ mPendingCoprocs.erase(it);
+ return;
+ }
+ }
+
+ LL_INFOS() << "Coprocedure with Id=" << id.asString() << " was not found." << LL_ENDL;
+}
+
+//=========================================================================
+void LLCoprocedureManager::coprocedureInvokerCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter)
+{
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ while (!mShutdown)
+ {
+ llcoro::waitForEventOn(mWakeupTrigger);
+ if (mShutdown)
+ break;
+
+ while (!mPendingCoprocs.empty())
+ {
+ QueuedCoproc::ptr_t coproc = mPendingCoprocs.front();
+ mPendingCoprocs.pop_front();
+ mActiveCoprocs.insert(ActiveCoproc_t::value_type(coproc->mId, httpAdapter));
+
+ LL_INFOS() << "Dequeued and invoking coprocedure(" << coproc->mName << ") with id=" << coproc->mId.asString() << LL_ENDL;
+
+ try
+ {
+ coproc->mProc(httpAdapter, coproc->mId);
+ }
+ catch (std::exception &e)
+ {
+ LL_WARNS() << "Coprocedure(" << coproc->mName << ") id=" << coproc->mId.asString() <<
+ " threw an exception! Message=\"" << e.what() << "\"" << LL_ENDL;
+ }
+ catch (...)
+ {
+ LL_WARNS() << "A non std::exception was thrown from " << coproc->mName << " with id=" << coproc->mId << "." << LL_ENDL;
+ }
+
+ LL_INFOS() << "Finished coprocedure(" << coproc->mName << ")" << LL_ENDL;
+
+ ActiveCoproc_t::iterator itActive = mActiveCoprocs.find(coproc->mId);
+ if (itActive != mActiveCoprocs.end())
+ {
+ mActiveCoprocs.erase(itActive);
+ }
+ }
+ }
+}
diff --git a/indra/newview/llcoproceduremanager.h b/indra/newview/llcoproceduremanager.h
new file mode 100644
index 0000000000..6ba3891e87
--- /dev/null
+++ b/indra/newview/llcoproceduremanager.h
@@ -0,0 +1,117 @@
+/**
+* @file llcoproceduremanager.h
+* @author Rider Linden
+* @brief Singleton class for managing asset uploads to the sim.
+*
+* $LicenseInfo:firstyear=2015&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2015, 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_COPROCEDURE_MANAGER_H
+#define LL_COPROCEDURE_MANAGER_H
+
+#include "lleventcoro.h"
+#include "llcoros.h"
+#include "llcorehttputil.h"
+#include "lluuid.h"
+
+class LLCoprocedureManager : public LLSingleton < LLCoprocedureManager >
+{
+public:
+ typedef boost::function<void(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &, const LLUUID &id)> CoProcedure_t;
+
+ LLCoprocedureManager();
+ virtual ~LLCoprocedureManager();
+
+ /// Places the coprocedure on the queue for processing.
+ ///
+ /// @param name Is used for debugging and should identify this coroutine.
+ /// @param proc Is a bound function to be executed
+ ///
+ /// @return This method returns a UUID that can be used later to cancel execution.
+ LLUUID enqueueCoprocedure(const std::string &name, CoProcedure_t proc);
+
+ /// Cancel a coprocedure. If the coprocedure is already being actively executed
+ /// this method calls cancelYieldingOperation() on the associated HttpAdapter
+ /// If it has not yet been dequeued it is simply removed from the queue.
+ void cancelCoprocedure(const LLUUID &id);
+
+ /// Requests a shutdown of the upload manager. Passing 'true' will perform
+ /// an immediate kill on the upload coroutine.
+ void shutdown(bool hardShutdown = false);
+
+ /// Returns the number of coprocedures in the queue awaiting processing.
+ ///
+ inline size_t countPending() const
+ {
+ return mPendingCoprocs.size();
+ }
+
+ /// Returns the number of coprocedures actively being processed.
+ ///
+ inline size_t countActive() const
+ {
+ return mActiveCoprocs.size();
+ }
+
+ /// Returns the total number of coprocedures either queued or in active processing.
+ ///
+ inline size_t count() const
+ {
+ return countPending() + countActive();
+ }
+
+private:
+ struct QueuedCoproc
+ {
+ typedef boost::shared_ptr<QueuedCoproc> ptr_t;
+
+ QueuedCoproc(const std::string &name, const LLUUID &id, CoProcedure_t proc):
+ mName(name),
+ mId(id),
+ mProc(proc)
+ {}
+
+ std::string mName;
+ LLUUID mId;
+ CoProcedure_t mProc;
+ };
+
+ // we use a deque here rather than std::queue since we want to be able to
+ // iterate through the queue and potentially erase an entry from the middle.
+ typedef std::deque<QueuedCoproc::ptr_t> CoprocQueue_t;
+ typedef std::map<LLUUID, LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t> ActiveCoproc_t;
+
+ CoprocQueue_t mPendingCoprocs;
+ ActiveCoproc_t mActiveCoprocs;
+ bool mShutdown;
+ LLEventStream mWakeupTrigger;
+
+
+ typedef std::map<std::string, LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t> CoroAdapterMap_t;
+ LLCore::HttpRequest::policy_t mHTTPPolicy;
+
+ CoroAdapterMap_t mCoroMapping;
+
+ void coprocedureInvokerCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter);
+};
+
+#endif
diff --git a/indra/newview/llestateinfomodel.cpp b/indra/newview/llestateinfomodel.cpp
index 78d619a315..884d1579e6 100755
--- a/indra/newview/llestateinfomodel.cpp
+++ b/indra/newview/llestateinfomodel.cpp
@@ -29,7 +29,6 @@
#include "llestateinfomodel.h"
// libs
-#include "llhttpclient.h"
#include "llregionflags.h"
#include "message.h"
@@ -38,6 +37,8 @@
#include "llfloaterregioninfo.h" // for invoice id
#include "llviewerregion.h"
+#include "llcorehttputil.h"
+
LLEstateInfoModel::LLEstateInfoModel()
: mID(0)
, mFlags(0)
@@ -110,24 +111,6 @@ void LLEstateInfoModel::notifyCommit()
//== PRIVATE STUFF ============================================================
-class LLEstateChangeInfoResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(LLEstateChangeInfoResponder);
-protected:
- // if we get a normal response, handle it here
- virtual void httpSuccesss()
- {
- LL_INFOS() << "Committed estate info" << LL_ENDL;
- LLEstateInfoModel::instance().notifyCommit();
- }
-
- // if we get an error response
- virtual void httpFailure()
- {
- LL_WARNS() << "Failed to commit estate info " << dumpResponse() << LL_ENDL;
- }
-};
-
// tries to send estate info using a cap; returns true if it succeeded
bool LLEstateInfoModel::commitEstateInfoCaps()
{
@@ -139,29 +122,53 @@ bool LLEstateInfoModel::commitEstateInfoCaps()
return false;
}
- LLSD body;
- body["estate_name" ] = getName();
- body["sun_hour" ] = getSunHour();
+ LLCoros::instance().launch("LLEstateInfoModel::commitEstateInfoCapsCoro",
+ boost::bind(&LLEstateInfoModel::commitEstateInfoCapsCoro, this, url));
- body["is_sun_fixed" ] = getUseFixedSun();
- body["is_externally_visible"] = getIsExternallyVisible();
- body["allow_direct_teleport"] = getAllowDirectTeleport();
- body["deny_anonymous" ] = getDenyAnonymous();
- body["deny_age_unverified" ] = getDenyAgeUnverified();
- body["allow_voice_chat" ] = getAllowVoiceChat();
-
- body["invoice" ] = LLFloaterRegionInfo::getLastInvoice();
-
- LL_DEBUGS("Windlight Sync") << "Sending estate caps: "
- << "is_sun_fixed = " << getUseFixedSun()
- << ", sun_hour = " << getSunHour() << LL_ENDL;
- LL_DEBUGS() << body << LL_ENDL;
-
- // we use a responder so that we can re-get the data after committing to the database
- LLHTTPClient::post(url, body, new LLEstateChangeInfoResponder);
return true;
}
+void LLEstateInfoModel::commitEstateInfoCapsCoro(std::string url)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("EstateChangeInfo", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLSD body;
+ body["estate_name"] = getName();
+ body["sun_hour"] = getSunHour();
+
+ body["is_sun_fixed"] = getUseFixedSun();
+ body["is_externally_visible"] = getIsExternallyVisible();
+ body["allow_direct_teleport"] = getAllowDirectTeleport();
+ body["deny_anonymous"] = getDenyAnonymous();
+ body["deny_age_unverified"] = getDenyAgeUnverified();
+ body["allow_voice_chat"] = getAllowVoiceChat();
+
+ body["invoice"] = LLFloaterRegionInfo::getLastInvoice();
+
+ LL_DEBUGS("Windlight Sync") << "Sending estate caps: "
+ << "is_sun_fixed = " << getUseFixedSun()
+ << ", sun_hour = " << getSunHour() << LL_ENDL;
+ LL_DEBUGS() << body << LL_ENDL;
+
+ LLSD result = httpAdapter->postAndYield(httpRequest, url, body);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (status)
+ {
+ LL_INFOS() << "Committed estate info" << LL_ENDL;
+ LLEstateInfoModel::instance().notifyCommit();
+ }
+ else
+ {
+ LL_WARNS() << "Failed to commit estate info " << LL_ENDL;
+ }
+}
+
/* This is the old way of doing things, is deprecated, and should be
deleted when the dataserver model can be removed */
// key = "estatechangeinfo"
diff --git a/indra/newview/llestateinfomodel.h b/indra/newview/llestateinfomodel.h
index 538f2f7c75..fcfbd1ce7d 100755
--- a/indra/newview/llestateinfomodel.h
+++ b/indra/newview/llestateinfomodel.h
@@ -30,6 +30,8 @@
class LLMessageSystem;
#include "llsingleton.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
/**
* Contains estate info, notifies interested parties of its changes.
@@ -73,7 +75,6 @@ protected:
friend class LLSingleton<LLEstateInfoModel>;
friend class LLDispatchEstateUpdateInfo;
- friend class LLEstateChangeInfoResponder;
LLEstateInfoModel();
@@ -99,6 +100,8 @@ private:
update_signal_t mUpdateSignal; /// emitted when we receive update from sim
update_signal_t mCommitSignal; /// emitted when our update gets applied to sim
+
+ void commitEstateInfoCapsCoro(std::string url);
};
inline bool LLEstateInfoModel::getFlag(U64 flag) const
diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp
index 4de6ad4d2f..0aad1d5ba9 100755
--- a/indra/newview/lleventpoll.cpp
+++ b/indra/newview/lleventpoll.cpp
@@ -30,261 +30,248 @@
#include "llappviewer.h"
#include "llagent.h"
-#include "llhttpclient.h"
-#include "llhttpconstants.h"
#include "llsdserialize.h"
#include "lleventtimer.h"
#include "llviewerregion.h"
#include "message.h"
#include "lltrans.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
+#include "llcorehttputil.h"
+#include "lleventfilter.h"
-namespace
+namespace LLEventPolling
{
- // We will wait RETRY_SECONDS + (errorCount * RETRY_SECONDS_INC) before retrying after an error.
- // This means we attempt to recover relatively quickly but back off giving more time to recover
- // until we finally give up after MAX_EVENT_POLL_HTTP_ERRORS attempts.
- const F32 EVENT_POLL_ERROR_RETRY_SECONDS = 15.f; // ~ half of a normal timeout.
- const F32 EVENT_POLL_ERROR_RETRY_SECONDS_INC = 5.f; // ~ half of a normal timeout.
- const S32 MAX_EVENT_POLL_HTTP_ERRORS = 10; // ~5 minutes, by the above rules.
-
- class LLEventPollResponder : public LLHTTPClient::Responder
- {
- LOG_CLASS(LLEventPollResponder);
- public:
-
- static LLHTTPClient::ResponderPtr start(const std::string& pollURL, const LLHost& sender);
- void stop();
-
- 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 httpFailure();
- /* virtual */ void httpSuccess();
-
- private:
-
- bool mDone;
-
- std::string mPollURL;
- std::string mSender;
-
- LLSD mAcknowledge;
-
- // these are only here for debugging so we can see which poller is which
- static int sCount;
- int mCount;
- S32 mErrorCount;
- };
-
- class LLEventPollEventTimer : public LLEventTimer
- {
- typedef LLPointer<LLEventPollResponder> EventPollResponderPtr;
-
- public:
- LLEventPollEventTimer(F32 period, EventPollResponderPtr responder)
- : LLEventTimer(period), mResponder(responder)
- { }
-
- virtual BOOL tick()
- {
- mResponder->makeRequest();
- return TRUE; // Causes this instance to be deleted.
- }
-
- private:
-
- EventPollResponderPtr mResponder;
- };
-
- //static
- LLHTTPClient::ResponderPtr LLEventPollResponder::start(
- const std::string& pollURL, const LLHost& sender)
- {
- LLHTTPClient::ResponderPtr result = new LLEventPollResponder(pollURL, sender);
- LL_INFOS() << "LLEventPollResponder::start <" << sCount << "> "
- << pollURL << LL_ENDL;
- return result;
- }
-
- void LLEventPollResponder::stop()
- {
- LL_INFOS() << "LLEventPollResponder::stop <" << mCount << "> "
- << mPollURL << LL_ENDL;
- // there should be a way to stop a LLHTTPClient request in progress
- mDone = true;
- }
-
- int LLEventPollResponder::sCount = 0;
-
- LLEventPollResponder::LLEventPollResponder(const std::string& pollURL, const LLHost& sender)
- : mDone(false),
- mPollURL(pollURL),
- mCount(++sCount),
- mErrorCount(0)
- {
- //extract host and port of simulator to set as sender
- LLViewerRegion *regionp = gAgent.getRegion();
- if (!regionp)
- {
- LL_ERRS() << "LLEventPoll initialized before region is added." << LL_ENDL;
- }
- mSender = sender.getIPandPort();
- LL_INFOS() << "LLEventPoll initialized with sender " << mSender << LL_ENDL;
- makeRequest();
- }
-
- LLEventPollResponder::~LLEventPollResponder()
- {
- stop();
- LL_DEBUGS() << "LLEventPollResponder::~Impl <" << mCount << "> "
- << mPollURL << LL_ENDL;
- }
-
- // virtual
- void LLEventPollResponder::completedRaw(const LLChannelDescriptors& channels,
- const LLIOPipe::buffer_ptr_t& buffer)
- {
- if (getStatus() == HTTP_BAD_GATEWAY)
- {
- // These errors are not parsable as LLSD,
- // which LLHTTPClient::Responder::completedRaw will try to do.
- httpCompleted();
- }
- else
- {
- LLHTTPClient::Responder::completedRaw(channels,buffer);
- }
- }
-
- void LLEventPollResponder::makeRequest()
- {
- LLSD request;
- request["ack"] = mAcknowledge;
- request["done"] = mDone;
-
- LL_DEBUGS() << "LLEventPollResponder::makeRequest <" << mCount << "> ack = "
- << LLSDXMLStreamer(mAcknowledge) << LL_ENDL;
- LLHTTPClient::post(mPollURL, request, this);
- }
-
- void LLEventPollResponder::handleMessage(const LLSD& content)
- {
- std::string msg_name = content["message"];
- LLSD message;
- message["sender"] = mSender;
- message["body"] = content["body"];
- LLMessageSystem::dispatch(msg_name, message);
- }
-
- //virtual
- 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 ( getStatus() == HTTP_BAD_GATEWAY )
- {
- mErrorCount = 0;
- makeRequest();
- }
- else if (mErrorCount < MAX_EVENT_POLL_HTTP_ERRORS)
- {
- ++mErrorCount;
-
- // The 'tick' will return TRUE causing the timer to delete this.
- new LLEventPollEventTimer(EVENT_POLL_ERROR_RETRY_SECONDS
- + mErrorCount * EVENT_POLL_ERROR_RETRY_SECONDS_INC
- , this);
-
- LL_WARNS() << dumpResponse() << LL_ENDL;
- }
- else
- {
- LL_WARNS() << dumpResponse()
- << " [count:" << mCount << "] "
- << (mDone ? " -- done" : "") << LL_ENDL;
- stop();
-
- // At this point we have given up and the viewer will not receive HTTP messages from the simulator.
- // IMs, teleports, about land, selecing land, region crossing and more will all fail.
- // They are essentially disconnected from the region even though some things may still work.
- // Since things won't get better until they relog we force a disconnect now.
-
- // *NOTE:Mani - The following condition check to see if this failing event poll
- // is attached to the Agent's main region. If so we disconnect the viewer.
- // Else... its a child region and we just leave the dead event poll stopped and
- // continue running.
- if(gAgent.getRegion() && gAgent.getRegion()->getHost().getIPandPort() == mSender)
- {
- LL_WARNS() << "Forcing disconnect due to stalled main region event poll." << LL_ENDL;
- LLAppViewer::instance()->forceDisconnect(LLTrans::getString("AgentLostConnection"));
- }
- }
- }
-
- //virtual
- void LLEventPollResponder::httpSuccess()
- {
- LL_DEBUGS() << "LLEventPollResponder::result <" << mCount << ">"
- << (mDone ? " -- done" : "") << LL_ENDL;
-
- if (mDone) return;
-
- mErrorCount = 0;
-
- const LLSD& content = getContent();
- if (!content.isMap() ||
- !content.get("events") ||
- !content.get("id"))
- {
- LL_WARNS() << "received event poll with no events or id key: " << dumpResponse() << LL_ENDL;
- makeRequest();
- return;
- }
-
- mAcknowledge = content["id"];
- LLSD events = content["events"];
-
- if(mAcknowledge.isUndefined())
- {
- LL_WARNS() << "LLEventPollResponder: id undefined" << LL_ENDL;
- }
-
- // was LL_INFOS() but now that CoarseRegionUpdate is TCP @ 1/second, it'd be too verbose for viewer logs. -MG
- LL_DEBUGS() << "LLEventPollResponder::httpSuccess <" << mCount << "> " << events.size() << "events (id "
- << LLSDXMLStreamer(mAcknowledge) << ")" << LL_ENDL;
-
- LLSD::array_const_iterator i = events.beginArray();
- LLSD::array_const_iterator end = events.endArray();
- for (; i != end; ++i)
- {
- if (i->has("message"))
- {
- handleMessage(*i);
- }
- }
-
- makeRequest();
- }
+namespace Details
+{
+
+ class LLEventPollImpl
+ {
+ public:
+ LLEventPollImpl(const LLHost &sender);
+
+ void start(const std::string &url);
+ void stop();
+
+ private:
+ // We will wait RETRY_SECONDS + (errorCount * RETRY_SECONDS_INC) before retrying after an error.
+ // This means we attempt to recover relatively quickly but back off giving more time to recover
+ // until we finally give up after MAX_EVENT_POLL_HTTP_ERRORS attempts.
+ static const F32 EVENT_POLL_ERROR_RETRY_SECONDS;
+ static const F32 EVENT_POLL_ERROR_RETRY_SECONDS_INC;
+ static const S32 MAX_EVENT_POLL_HTTP_ERRORS;
+
+ void eventPollCoro(std::string url);
+
+ void handleMessage(const LLSD &content);
+
+ bool mDone;
+ LLCore::HttpRequest::ptr_t mHttpRequest;
+ LLCore::HttpRequest::policy_t mHttpPolicy;
+ std::string mSenderIp;
+ int mCounter;
+ LLCoreHttpUtil::HttpCoroutineAdapter::wptr_t mAdapter;
+
+ static int sNextCounter;
+ };
+
+
+ const F32 LLEventPollImpl::EVENT_POLL_ERROR_RETRY_SECONDS = 15.f; // ~ half of a normal timeout.
+ const F32 LLEventPollImpl::EVENT_POLL_ERROR_RETRY_SECONDS_INC = 5.f; // ~ half of a normal timeout.
+ const S32 LLEventPollImpl::MAX_EVENT_POLL_HTTP_ERRORS = 10; // ~5 minutes, by the above rules.
+
+ int LLEventPollImpl::sNextCounter = 1;
+
+
+ LLEventPollImpl::LLEventPollImpl(const LLHost &sender) :
+ mDone(false),
+ mHttpRequest(),
+ mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID),
+ mSenderIp(),
+ mCounter(sNextCounter++)
+
+ {
+ LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp());
+
+ mHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest);
+ mHttpPolicy = app_core_http.getPolicy(LLAppCoreHttp::AP_LONG_POLL);
+ mSenderIp = sender.getIPandPort();
+ }
+
+ void LLEventPollImpl::handleMessage(const LLSD& content)
+ {
+ std::string msg_name = content["message"];
+ LLSD message;
+ message["sender"] = mSenderIp;
+ message["body"] = content["body"];
+ LLMessageSystem::dispatch(msg_name, message);
+ }
+
+ void LLEventPollImpl::start(const std::string &url)
+ {
+ if (!url.empty())
+ {
+ std::string coroname =
+ LLCoros::instance().launch("LLEventPollImpl::eventPollCoro",
+ boost::bind(&LLEventPollImpl::eventPollCoro, this, url));
+ LL_INFOS("LLEventPollImpl") << coroname << " with url '" << url << LL_ENDL;
+ }
+ }
+
+ void LLEventPollImpl::stop()
+ {
+ LL_INFOS() << "requesting stop for event poll coroutine <" << mCounter << ">" << LL_ENDL;
+ mDone = true;
+
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter = mAdapter.lock();
+ if (adapter)
+ {
+ // cancel the yielding operation if any.
+ adapter->cancelYieldingOperation();
+ }
+ }
+
+ void LLEventPollImpl::eventPollCoro(std::string url)
+ {
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("EventPoller", mHttpPolicy));
+ LLSD acknowledge;
+ int errorCount = 0;
+ int counter = mCounter; // saved on the stack for logging.
+
+ LL_INFOS("LLEventPollImpl") << " <" << counter << "> entering coroutine." << LL_ENDL;
+
+ mAdapter = httpAdapter;
+
+ // continually poll for a server update until we've been flagged as
+ // finished
+ while (!mDone)
+ {
+ LLSD request;
+ request["ack"] = acknowledge;
+ request["done"] = mDone;
+
+// LL_DEBUGS("LLEventPollImpl::eventPollCoro") << "<" << counter << "> request = "
+// << LLSDXMLStreamer(request) << LL_ENDL;
+
+ LL_DEBUGS("LLEventPollImpl") << " <" << counter << "> posting and yielding." << LL_ENDL;
+ LLSD result = httpAdapter->postAndYield(mHttpRequest, url, request);
+
+// LL_DEBUGS("LLEventPollImpl::eventPollCoro") << "<" << counter << "> result = "
+// << LLSDXMLStreamer(result) << LL_ENDL;
+
+ LLSD httpResults = result["http_result"];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ if (status == LLCore::HttpStatus(HTTP_BAD_GATEWAY))
+ { // A HTTP_BAD_GATEWAY (502) error is our standard timeout response
+ // we get this when there are no events.
+ errorCount = 0;
+ continue;
+ }
+ else if ((status == LLCore::HttpStatus(LLCore::HttpStatus::LLCORE, LLCore::HE_OP_CANCELED)) ||
+ (status == LLCore::HttpStatus(HTTP_NOT_FOUND)))
+ { // Event polling for this server has been canceled. In
+ // some cases the server gets ahead of the viewer and will
+ // return a 404 error (Not Found) before the cancel event
+ // comes back in the queue
+ LL_WARNS() << "Canceling coroutine" << LL_ENDL;
+ break;
+ }
+ LL_WARNS("LLEventPollImpl") << "<" << counter << "> Error result from LLCoreHttpUtil::HttpCoroHandler. Code "
+ << status.toTerseString() << ": '" << httpResults["message"] << "'" << LL_ENDL;
+
+ if (errorCount < MAX_EVENT_POLL_HTTP_ERRORS)
+ { // An unanticipated error has been received from our poll
+ // request. Calculate a timeout and wait for it to expire(sleep)
+ // before trying again. The sleep time is increased by 5 seconds
+ // for each consecutive error.
+ LLEventTimeout timeout;
+ ++errorCount;
+
+ F32 waitToRetry = EVENT_POLL_ERROR_RETRY_SECONDS
+ + errorCount * EVENT_POLL_ERROR_RETRY_SECONDS_INC;
+
+ LL_WARNS("LLEventPollImpl") << "<" << counter << "> Retrying in " << waitToRetry <<
+ " seconds, error count is now " << errorCount << LL_ENDL;
+
+ timeout.eventAfter(waitToRetry, LLSD());
+ llcoro::waitForEventOn(timeout);
+
+ if (mDone)
+ break;
+ LL_INFOS("LLEventPollImpl") << "<" << counter << "> About to retry request." << LL_ENDL;
+ continue;
+ }
+ else
+ {
+ // At this point we have given up and the viewer will not receive HTTP messages from the simulator.
+ // IMs, teleports, about land, selecting land, region crossing and more will all fail.
+ // They are essentially disconnected from the region even though some things may still work.
+ // Since things won't get better until they relog we force a disconnect now.
+ mDone = true;
+
+ // *NOTE:Mani - The following condition check to see if this failing event poll
+ // is attached to the Agent's main region. If so we disconnect the viewer.
+ // Else... its a child region and we just leave the dead event poll stopped and
+ // continue running.
+ if (gAgent.getRegion() && gAgent.getRegion()->getHost().getIPandPort() == mSenderIp)
+ {
+ LL_WARNS("LLEventPollImpl") << "< " << counter << "> Forcing disconnect due to stalled main region event poll." << LL_ENDL;
+ LLAppViewer::instance()->forceDisconnect(LLTrans::getString("AgentLostConnection"));
+ }
+ break;
+ }
+ }
+
+ errorCount = 0;
+
+ if (!result.isMap() ||
+ !result.get("events") ||
+ !result.get("id"))
+ {
+ LL_WARNS("LLEventPollImpl") << " <" << counter << "> received event poll with no events or id key: " << LLSDXMLStreamer(result) << LL_ENDL;
+ continue;
+ }
+
+ acknowledge = result["id"];
+ LLSD events = result["events"];
+
+ if (acknowledge.isUndefined())
+ {
+ LL_WARNS("LLEventPollImpl") << " id undefined" << LL_ENDL;
+ }
+
+ // was LL_INFOS() but now that CoarseRegionUpdate is TCP @ 1/second, it'd be too verbose for viewer logs. -MG
+ LL_DEBUGS("LLEventPollImpl") << " <" << counter << "> " << events.size() << "events (id " << LLSDXMLStreamer(acknowledge) << ")" << LL_ENDL;
+
+ LLSD::array_const_iterator i = events.beginArray();
+ LLSD::array_const_iterator end = events.endArray();
+ for (; i != end; ++i)
+ {
+ if (i->has("message"))
+ {
+ handleMessage(*i);
+ }
+ }
+ }
+ LL_INFOS("LLEventPollImpl") << " <" << counter << "> Leaving coroutine." << LL_ENDL;
+ }
+
+}
}
-LLEventPoll::LLEventPoll(const std::string& poll_url, const LLHost& sender)
- : mImpl(LLEventPollResponder::start(poll_url, sender))
- { }
+LLEventPoll::LLEventPoll(const std::string& poll_url, const LLHost& sender):
+ mImpl()
+{
+ mImpl = boost::unique_ptr<LLEventPolling::Details::LLEventPollImpl>
+ (new LLEventPolling::Details::LLEventPollImpl(sender));
+ mImpl->start(poll_url);
+}
LLEventPoll::~LLEventPoll()
{
- LLHTTPClient::Responder* responderp = mImpl.get();
- LLEventPollResponder* event_poll_responder = dynamic_cast<LLEventPollResponder*>(responderp);
- if (event_poll_responder) event_poll_responder->stop();
+ mImpl->stop();
+
}
diff --git a/indra/newview/lleventpoll.h b/indra/newview/lleventpoll.h
index e8d98062aa..e32b4ed322 100755
--- a/indra/newview/lleventpoll.h
+++ b/indra/newview/lleventpoll.h
@@ -28,9 +28,23 @@
#define LL_LLEVENTPOLL_H
#include "llhttpclient.h"
+#include "boost/move/unique_ptr.hpp"
+
+namespace boost
+{
+ using ::boost::movelib::unique_ptr; // move unique_ptr into the boost namespace.
+}
class LLHost;
+namespace LLEventPolling
+{
+namespace Details
+{
+ class LLEventPollImpl;
+}
+}
+
class LLEventPoll
///< implements the viewer side of server-to-viewer pushed events.
@@ -40,11 +54,11 @@ public:
///< Start polling the URL.
virtual ~LLEventPoll();
- ///< will stop polling, cancelling any poll in progress.
+ ///< will stop polling, canceling any poll in progress.
private:
- LLHTTPClient::ResponderPtr mImpl;
+ boost::unique_ptr<LLEventPolling::Details::LLEventPollImpl> mImpl;
};
diff --git a/indra/newview/llfacebookconnect.cpp b/indra/newview/llfacebookconnect.cpp
index 28319564e4..136e02953c 100755
--- a/indra/newview/llfacebookconnect.cpp
+++ b/indra/newview/llfacebookconnect.cpp
@@ -34,7 +34,6 @@
#include "llagent.h"
#include "llcallingcard.h" // for LLAvatarTracker
#include "llcommandhandler.h"
-#include "llhttpclient.h"
#include "llnotificationsutil.h"
#include "llurlaction.h"
#include "llimagepng.h"
@@ -42,9 +41,11 @@
#include "lltrans.h"
#include "llevents.h"
#include "llviewerregion.h"
+#include "llviewercontrol.h"
#include "llfloaterwebcontent.h"
#include "llfloaterreg.h"
+#include "llcorehttputil.h"
boost::scoped_ptr<LLEventPump> LLFacebookConnect::sStateWatcher(new LLEventStream("FacebookConnectState"));
boost::scoped_ptr<LLEventPump> LLFacebookConnect::sInfoWatcher(new LLEventStream("FacebookConnectInfo"));
@@ -67,6 +68,24 @@ void toast_user_for_facebook_success()
LLNotificationsUtil::add("FacebookConnect", args);
}
+LLCore::HttpHeaders::ptr_t get_headers()
+{
+ LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
+ // The DebugSlshareLogTag mechanism is intended to trigger slshare-service
+ // debug logging. slshare-service is coded to respond to an X-debug-tag
+ // header by engaging debug logging for that request only. This way a
+ // developer need not muck with the slshare-service image to engage debug
+ // logging. Moreover, the value of X-debug-tag is embedded in each such
+ // log line so the developer can quickly find the log lines pertinent to
+ // THIS session.
+ std::string logtag(gSavedSettings.getString("DebugSlshareLogTag"));
+ if (! logtag.empty())
+ {
+ httpHeaders->append("X-debug-tag", logtag);
+ }
+ return httpHeaders;
+}
+
///////////////////////////////////////////////////////////////////////////////
//
class LLFacebookConnectHandler : public LLCommandHandler
@@ -125,266 +144,354 @@ LLFacebookConnectHandler gFacebookConnectHandler;
///////////////////////////////////////////////////////////////////////////////
//
-class LLFacebookConnectResponder : public LLHTTPClient::Responder
+void LLFacebookConnect::facebookConnectCoro(std::string authCode, std::string authState)
{
- LOG_CLASS(LLFacebookConnectResponder);
-public:
-
- LLFacebookConnectResponder()
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+ LLSD putData;
+ if (!authCode.empty())
{
- LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTION_IN_PROGRESS);
+ putData["code"] = authCode;
+ }
+ if (!authState.empty())
+ {
+ putData["state"] = authState;
}
-
- /* virtual */ void httpSuccess()
- {
- LL_DEBUGS("FacebookConnect") << "Connect successful. " << dumpResponse() << LL_ENDL;
- LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTED);
- }
- /* virtual */ void httpFailure()
- {
- if ( HTTP_FOUND == getStatus() )
- {
- const std::string& location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
- if (location.empty())
- {
- LL_WARNS("FacebookConnect") << "Missing Location header " << dumpResponse()
- << "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
- }
- else
- {
- LLFacebookConnect::instance().openFacebookWeb(location);
- }
- }
- else
- {
- LL_WARNS("FacebookConnect") << dumpResponse() << LL_ENDL;
- LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTION_FAILED);
- const LLSD& content = getContent();
- log_facebook_connect_error("Connect", getStatus(), getReason(),
- content.get("error_code"), content.get("error_description"));
- }
- }
-};
+ httpOpts->setWantHeaders(true);
+ httpOpts->setFollowRedirects(false);
+
+ setConnectionState(LLFacebookConnect::FB_CONNECTION_IN_PROGRESS);
+
+ LLSD result = httpAdapter->putAndYield(httpRequest, getFacebookConnectURL("/connection"), putData, httpOpts, get_headers());
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+ if (!status)
+ {
+ if (status == LLCore::HttpStatus(HTTP_FOUND))
+ {
+ std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
+ if (location.empty())
+ {
+ LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL;
+ }
+ else
+ {
+ openFacebookWeb(location);
+ }
+ }
+ }
+ else
+ {
+ LL_INFOS("FacebookConnect") << "Connect successful. " << LL_ENDL;
+ setConnectionState(LLFacebookConnect::FB_CONNECTED);
+ }
+
+}
///////////////////////////////////////////////////////////////////////////////
//
-class LLFacebookShareResponder : public LLHTTPClient::Responder
+bool LLFacebookConnect::testShareStatus(LLSD &result)
{
- LOG_CLASS(LLFacebookShareResponder);
-public:
-
- LLFacebookShareResponder()
- {
- LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_POSTING);
- }
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
- /* virtual */ void httpSuccess()
- {
- toast_user_for_facebook_success();
- LL_DEBUGS("FacebookConnect") << "Post successful. " << dumpResponse() << LL_ENDL;
- LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_POSTED);
- }
+ if (status)
+ return true;
- /* virtual */ void httpFailure()
- {
- if ( HTTP_FOUND == getStatus() )
- {
- const std::string& location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
- if (location.empty())
- {
- LL_WARNS("FacebookConnect") << "Missing Location header " << dumpResponse()
- << "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
- }
- else
- {
- LLFacebookConnect::instance().openFacebookWeb(location);
- }
- }
- else if ( HTTP_NOT_FOUND == getStatus() )
- {
- LLFacebookConnect::instance().connectToFacebook();
- }
- else
- {
- LL_WARNS("FacebookConnect") << dumpResponse() << LL_ENDL;
- LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_POST_FAILED);
- const LLSD& content = getContent();
- log_facebook_connect_error("Share", getStatus(), getReason(),
- content.get("error_code"), content.get("error_description"));
- }
- }
-};
+ if (status == LLCore::HttpStatus(HTTP_FOUND))
+ {
+ std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
+ if (location.empty())
+ {
+ LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL;
+ }
+ else
+ {
+ openFacebookWeb(location);
+ }
+ }
+ if (status == LLCore::HttpStatus(HTTP_NOT_FOUND))
+ {
+ LL_DEBUGS("FacebookConnect") << "Not connected. " << LL_ENDL;
+ connectToFacebook();
+ }
+ else
+ {
+ LL_WARNS("FacebookConnect") << "HTTP Status error " << status.toString() << LL_ENDL;
+ setConnectionState(LLFacebookConnect::FB_POST_FAILED);
+ log_facebook_connect_error("Share", status.getStatus(), status.toString(),
+ result.get("error_code"), result.get("error_description"));
+ }
+ return false;
+}
-///////////////////////////////////////////////////////////////////////////////
-//
-class LLFacebookDisconnectResponder : public LLHTTPClient::Responder
+void LLFacebookConnect::facebookShareCoro(std::string route, LLSD share)
{
- LOG_CLASS(LLFacebookDisconnectResponder);
-public:
-
- LLFacebookDisconnectResponder()
- {
- LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_DISCONNECTING);
- }
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
- void setUserDisconnected()
- {
- // Clear data
- LLFacebookConnect::instance().clearInfo();
- LLFacebookConnect::instance().clearContent();
- //Notify state change
- LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_NOT_CONNECTED);
- }
+ httpOpts->setWantHeaders(true);
+ httpOpts->setFollowRedirects(false);
- /* virtual */ void httpSuccess()
- {
- LL_DEBUGS("FacebookConnect") << "Disconnect successful. " << dumpResponse() << LL_ENDL;
- setUserDisconnected();
- }
+ setConnectionState(LLFacebookConnect::FB_POSTING);
- /* virtual */ void httpFailure()
- {
- //User not found so already disconnected
- if ( HTTP_NOT_FOUND == getStatus() )
- {
- LL_DEBUGS("FacebookConnect") << "Already disconnected. " << dumpResponse() << LL_ENDL;
- setUserDisconnected();
- }
- else
- {
- LL_WARNS("FacebookConnect") << dumpResponse() << LL_ENDL;
- LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_DISCONNECT_FAILED);
- const LLSD& content = getContent();
- log_facebook_connect_error("Disconnect", getStatus(), getReason(),
- content.get("error_code"), content.get("error_description"));
- }
- }
-};
+ LLSD result = httpAdapter->postAndYield(httpRequest, getFacebookConnectURL(route, true), share, httpOpts, get_headers());
+
+ if (testShareStatus(result))
+ {
+ toast_user_for_facebook_success();
+ LL_DEBUGS("FacebookConnect") << "Post successful. " << LL_ENDL;
+ setConnectionState(LLFacebookConnect::FB_POSTED);
+ }
+}
+
+void LLFacebookConnect::facebookShareImageCoro(std::string route, LLPointer<LLImageFormatted> image, std::string caption)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders(get_headers());
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+ httpOpts->setWantHeaders(true);
+ httpOpts->setFollowRedirects(false);
+
+ std::string imageFormat;
+ if (dynamic_cast<LLImagePNG*>(image.get()))
+ {
+ imageFormat = "png";
+ }
+ else if (dynamic_cast<LLImageJPEG*>(image.get()))
+ {
+ imageFormat = "jpg";
+ }
+ else
+ {
+ LL_WARNS() << "Image to upload is not a PNG or JPEG" << LL_ENDL;
+ return;
+ }
+
+ // All this code is mostly copied from LLWebProfile::post()
+ static const std::string boundary = "----------------------------0123abcdefab";
+
+ std::string contentType = "multipart/form-data; boundary=" + boundary;
+ httpHeaders->append("Content-Type", contentType.c_str());
+
+ LLCore::BufferArray::ptr_t raw = LLCore::BufferArray::ptr_t(new LLCore::BufferArray()); //
+ LLCore::BufferArrayStream body(raw.get());
+
+ // *NOTE: The order seems to matter.
+ body << "--" << boundary << "\r\n"
+ << "Content-Disposition: form-data; name=\"caption\"\r\n\r\n"
+ << caption << "\r\n";
+
+ body << "--" << boundary << "\r\n"
+ << "Content-Disposition: form-data; name=\"image\"; filename=\"Untitled." << imageFormat << "\"\r\n"
+ << "Content-Type: image/" << imageFormat << "\r\n\r\n";
+
+ // Insert the image data.
+ // *FIX: Treating this as a string will probably screw it up ...
+ U8* image_data = image->getData();
+ for (S32 i = 0; i < image->getDataSize(); ++i)
+ {
+ body << image_data[i];
+ }
+
+ body << "\r\n--" << boundary << "--\r\n";
+
+ setConnectionState(LLFacebookConnect::FB_POSTING);
+
+ LLSD result = httpAdapter->postAndYield(httpRequest, getFacebookConnectURL(route, true), raw, httpOpts, httpHeaders);
+
+ if (testShareStatus(result))
+ {
+ toast_user_for_facebook_success();
+ LL_DEBUGS("FacebookConnect") << "Post successful. " << LL_ENDL;
+ setConnectionState(LLFacebookConnect::FB_POSTED);
+ }
+}
///////////////////////////////////////////////////////////////////////////////
//
-class LLFacebookConnectedResponder : public LLHTTPClient::Responder
+void LLFacebookConnect::facebookDisconnectCoro()
{
- LOG_CLASS(LLFacebookConnectedResponder);
-public:
-
- LLFacebookConnectedResponder(bool auto_connect) : mAutoConnect(auto_connect)
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+ setConnectionState(LLFacebookConnect::FB_DISCONNECTING);
+ httpOpts->setFollowRedirects(false);
+
+ LLSD result = httpAdapter->deleteAndYield(httpRequest, getFacebookConnectURL("/connection"), httpOpts, get_headers());
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+ if (!status && (status != LLCore::HttpStatus(HTTP_FOUND)))
+ {
+ LL_WARNS("FacebookConnect") << "Failed to disconnect:" << status.toTerseString() << LL_ENDL;
+ setConnectionState(LLFacebookConnect::FB_DISCONNECT_FAILED);
+ log_facebook_connect_error("Disconnect", status.getStatus(), status.toString(),
+ result.get("error_code"), result.get("error_description"));
+ }
+ else
{
- LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTION_IN_PROGRESS);
+ LL_DEBUGS("FacebookConnect") << "Facebook Disconnect successful. " << LL_ENDL;
+ clearInfo();
+ clearContent();
+ //Notify state change
+ setConnectionState(LLFacebookConnect::FB_NOT_CONNECTED);
}
- /* virtual */ void httpSuccess()
- {
- LL_DEBUGS("FacebookConnect") << "Connect successful. " << dumpResponse() << LL_ENDL;
- LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTED);
- }
+}
- /* virtual */ void httpFailure()
- {
- // show the facebook login page if not connected yet
- if ( HTTP_NOT_FOUND == getStatus() )
- {
- LL_DEBUGS("FacebookConnect") << "Not connected. " << dumpResponse() << LL_ENDL;
- if (mAutoConnect)
- {
- LLFacebookConnect::instance().connectToFacebook();
- }
- else
- {
- LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_NOT_CONNECTED);
- }
- }
- else
- {
- LL_WARNS("FacebookConnect") << dumpResponse() << LL_ENDL;
- LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_DISCONNECT_FAILED);
- const LLSD& content = getContent();
- log_facebook_connect_error("Connected", getStatus(), getReason(),
- content.get("error_code"), content.get("error_description"));
- }
- }
-
-private:
- bool mAutoConnect;
-};
+///////////////////////////////////////////////////////////////////////////////
+//
+void LLFacebookConnect::facebookConnectedCheckCoro(bool autoConnect)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+ setConnectionState(LLFacebookConnect::FB_CONNECTION_IN_PROGRESS);
+
+ httpOpts->setFollowRedirects(false);
+
+ LLSD result = httpAdapter->getAndYield(httpRequest, getFacebookConnectURL("/connection", true), httpOpts, get_headers());
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ if ( status == LLCore::HttpStatus(HTTP_NOT_FOUND) )
+ {
+ LL_DEBUGS("FacebookConnect") << "Not connected. " << LL_ENDL;
+ if (autoConnect)
+ {
+ connectToFacebook();
+ }
+ else
+ {
+ setConnectionState(LLFacebookConnect::FB_NOT_CONNECTED);
+ }
+ }
+ else
+ {
+ LL_WARNS("FacebookConnect") << "Failed to test connection:" << status.toTerseString() << LL_ENDL;
+
+ setConnectionState(LLFacebookConnect::FB_DISCONNECT_FAILED);
+ log_facebook_connect_error("Connected", status.getStatus(), status.toString(),
+ result.get("error_code"), result.get("error_description"));
+ }
+ }
+ else
+ {
+ LL_DEBUGS("FacebookConnect") << "Connect successful. " << LL_ENDL;
+ setConnectionState(LLFacebookConnect::FB_CONNECTED);
+ }
+}
///////////////////////////////////////////////////////////////////////////////
//
-class LLFacebookInfoResponder : public LLHTTPClient::Responder
+void LLFacebookConnect::facebookConnectInfoCoro()
{
- LOG_CLASS(LLFacebookInfoResponder);
-public:
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
- /* virtual */ void httpSuccess()
- {
- LL_INFOS("FacebookConnect") << "Facebook: Info received" << LL_ENDL;
- LL_DEBUGS("FacebookConnect") << "Getting Facebook info successful. " << dumpResponse() << LL_ENDL;
- LLFacebookConnect::instance().storeInfo(getContent());
- }
+ httpOpts->setWantHeaders(true);
+ httpOpts->setFollowRedirects(false);
- /* virtual */ void httpFailure()
- {
- if ( HTTP_FOUND == getStatus() )
- {
- const std::string& location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
- if (location.empty())
- {
- LL_WARNS("FacebookConnect") << "Missing Location header " << dumpResponse()
- << "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
- }
- else
- {
- LLFacebookConnect::instance().openFacebookWeb(location);
- }
- }
- else
- {
- LL_WARNS("FacebookConnect") << dumpResponse() << LL_ENDL;
- const LLSD& content = getContent();
- log_facebook_connect_error("Info", getStatus(), getReason(),
- content.get("error_code"), content.get("error_description"));
- }
- }
-};
+ LLSD result = httpAdapter->getAndYield(httpRequest, getFacebookConnectURL("/info", true), httpOpts, get_headers());
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (status == LLCore::HttpStatus(HTTP_FOUND))
+ {
+ std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
+ if (location.empty())
+ {
+ LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL;
+ }
+ else
+ {
+ openFacebookWeb(location);
+ }
+ }
+ else if (!status)
+ {
+ LL_WARNS("FacebookConnect") << "Facebook Info failed: " << status.toString() << LL_ENDL;
+ log_facebook_connect_error("Info", status.getStatus(), status.toString(),
+ result.get("error_code"), result.get("error_description"));
+ }
+ else
+ {
+ LL_INFOS("FacebookConnect") << "Facebook: Info received" << LL_ENDL;
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ storeInfo(result);
+ }
+}
///////////////////////////////////////////////////////////////////////////////
//
-class LLFacebookFriendsResponder : public LLHTTPClient::Responder
+void LLFacebookConnect::facebookConnectFriendsCoro()
{
- LOG_CLASS(LLFacebookFriendsResponder);
-public:
-
- /* virtual */ void httpSuccess()
- {
- LL_DEBUGS("FacebookConnect") << "Getting Facebook friends successful. " << dumpResponse() << LL_ENDL;
- LLFacebookConnect::instance().storeContent(getContent());
- }
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
- /* virtual */ void httpFailure()
- {
- if ( HTTP_FOUND == getStatus() )
- {
- const std::string& location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
- if (location.empty())
- {
- LL_WARNS("FacebookConnect") << "Missing Location header " << dumpResponse()
- << "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
- }
- else
- {
- LLFacebookConnect::instance().openFacebookWeb(location);
- }
- }
- else
- {
- LL_WARNS("FacebookConnect") << dumpResponse() << LL_ENDL;
- const LLSD& content = getContent();
- log_facebook_connect_error("Friends", getStatus(), getReason(),
- content.get("error_code"), content.get("error_description"));
- }
- }
-};
+ httpOpts->setFollowRedirects(false);
+
+ LLSD result = httpAdapter->getAndYield(httpRequest, getFacebookConnectURL("/friends", true), httpOpts, get_headers());
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (status == LLCore::HttpStatus(HTTP_FOUND))
+ {
+ std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
+ if (location.empty())
+ {
+ LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL;
+ }
+ else
+ {
+ openFacebookWeb(location);
+ }
+ }
+ else if (!status)
+ {
+ LL_WARNS("FacebookConnect") << "Facebook Friends failed: " << status.toString() << LL_ENDL;
+ log_facebook_connect_error("Info", status.getStatus(), status.toString(),
+ result.get("error_code"), result.get("error_description"));
+ }
+ else
+ {
+ LL_INFOS("FacebookConnect") << "Facebook: Friends received" << LL_ENDL;
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ LLSD content = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT];
+ storeContent(content);
+ }
+}
///////////////////////////////////////////////////////////////////////////////
//
@@ -439,40 +546,28 @@ std::string LLFacebookConnect::getFacebookConnectURL(const std::string& route, b
void LLFacebookConnect::connectToFacebook(const std::string& auth_code, const std::string& auth_state)
{
- LLSD body;
- if (!auth_code.empty())
- {
- body["code"] = auth_code;
- }
- if (!auth_state.empty())
- {
- body["state"] = auth_state;
- }
-
- LLHTTPClient::put(getFacebookConnectURL("/connection"), body, new LLFacebookConnectResponder());
+ LLCoros::instance().launch("LLFacebookConnect::facebookConnectCoro",
+ boost::bind(&LLFacebookConnect::facebookConnectCoro, this, auth_code, auth_state));
}
void LLFacebookConnect::disconnectFromFacebook()
{
- LLHTTPClient::del(getFacebookConnectURL("/connection"), new LLFacebookDisconnectResponder());
+ LLCoros::instance().launch("LLFacebookConnect::facebookDisconnectCoro",
+ boost::bind(&LLFacebookConnect::facebookDisconnectCoro, this));
}
void LLFacebookConnect::checkConnectionToFacebook(bool auto_connect)
{
- const bool follow_redirects = false;
- const F32 timeout = HTTP_REQUEST_EXPIRY_SECS;
- LLHTTPClient::get(getFacebookConnectURL("/connection", true), new LLFacebookConnectedResponder(auto_connect),
- LLSD(), timeout, follow_redirects);
+ LLCoros::instance().launch("LLFacebookConnect::facebookConnectedCheckCoro",
+ boost::bind(&LLFacebookConnect::facebookConnectedCheckCoro, this, auto_connect));
}
void LLFacebookConnect::loadFacebookInfo()
{
if(mRefreshInfo)
{
- const bool follow_redirects = false;
- const F32 timeout = HTTP_REQUEST_EXPIRY_SECS;
- LLHTTPClient::get(getFacebookConnectURL("/info", true), new LLFacebookInfoResponder(),
- LLSD(), timeout, follow_redirects);
+ LLCoros::instance().launch("LLFacebookConnect::facebookConnectInfoCoro",
+ boost::bind(&LLFacebookConnect::facebookConnectInfoCoro, this));
}
}
@@ -480,14 +575,13 @@ void LLFacebookConnect::loadFacebookFriends()
{
if(mRefreshContent)
{
- const bool follow_redirects = false;
- const F32 timeout = HTTP_REQUEST_EXPIRY_SECS;
- LLHTTPClient::get(getFacebookConnectURL("/friends", true), new LLFacebookFriendsResponder(),
- LLSD(), timeout, follow_redirects);
+ LLCoros::instance().launch("LLFacebookConnect::facebookConnectFriendsCoro",
+ boost::bind(&LLFacebookConnect::facebookConnectFriendsCoro, this));
}
}
-void LLFacebookConnect::postCheckin(const std::string& location, const std::string& name, const std::string& description, const std::string& image, const std::string& message)
+void LLFacebookConnect::postCheckin(const std::string& location, const std::string& name,
+ const std::string& description, const std::string& image, const std::string& message)
{
LLSD body;
if (!location.empty())
@@ -511,80 +605,34 @@ void LLFacebookConnect::postCheckin(const std::string& location, const std::stri
body["message"] = message;
}
- // Note: we can use that route for different publish action. We should be able to use the same responder.
- LLHTTPClient::post(getFacebookConnectURL("/share/checkin", true), body, new LLFacebookShareResponder());
+ LLCoros::instance().launch("LLFacebookConnect::facebookShareCoro",
+ boost::bind(&LLFacebookConnect::facebookShareCoro, this, "/share/checkin", body));
}
void LLFacebookConnect::sharePhoto(const std::string& image_url, const std::string& caption)
{
+ // *TODO: I could not find an instace where this method is used. Remove?
LLSD body;
body["image"] = image_url;
body["caption"] = caption;
- // Note: we can use that route for different publish action. We should be able to use the same responder.
- LLHTTPClient::post(getFacebookConnectURL("/share/photo", true), body, new LLFacebookShareResponder());
+ LLCoros::instance().launch("LLFacebookConnect::facebookShareCoro",
+ boost::bind(&LLFacebookConnect::facebookShareCoro, this, "/share/photo", body));
}
void LLFacebookConnect::sharePhoto(LLPointer<LLImageFormatted> image, const std::string& caption)
{
- std::string imageFormat;
- if (dynamic_cast<LLImagePNG*>(image.get()))
- {
- imageFormat = "png";
- }
- else if (dynamic_cast<LLImageJPEG*>(image.get()))
- {
- imageFormat = "jpg";
- }
- else
- {
- LL_WARNS() << "Image to upload is not a PNG or JPEG" << LL_ENDL;
- return;
- }
-
- // All this code is mostly copied from LLWebProfile::post()
- const std::string boundary = "----------------------------0123abcdefab";
-
- LLSD headers;
- headers["Content-Type"] = "multipart/form-data; boundary=" + boundary;
-
- std::ostringstream body;
-
- // *NOTE: The order seems to matter.
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"caption\"\r\n\r\n"
- << caption << "\r\n";
-
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"image\"; filename=\"Untitled." << imageFormat << "\"\r\n"
- << "Content-Type: image/" << imageFormat << "\r\n\r\n";
-
- // Insert the image data.
- // *FIX: Treating this as a string will probably screw it up ...
- U8* image_data = image->getData();
- for (S32 i = 0; i < image->getDataSize(); ++i)
- {
- body << image_data[i];
- }
-
- body << "\r\n--" << boundary << "--\r\n";
-
- // postRaw() takes ownership of the buffer and releases it later.
- size_t size = body.str().size();
- U8 *data = new U8[size];
- memcpy(data, body.str().data(), size);
-
- // Note: we can use that route for different publish action. We should be able to use the same responder.
- LLHTTPClient::postRaw(getFacebookConnectURL("/share/photo", true), data, size, new LLFacebookShareResponder(), headers);
+ LLCoros::instance().launch("LLFacebookConnect::facebookShareImageCoro",
+ boost::bind(&LLFacebookConnect::facebookShareImageCoro, this, "/share/photo", image, caption));
}
void LLFacebookConnect::updateStatus(const std::string& message)
{
LLSD body;
body["message"] = message;
-
- // Note: we can use that route for different publish action. We should be able to use the same responder.
- LLHTTPClient::post(getFacebookConnectURL("/share/wall", true), body, new LLFacebookShareResponder());
+
+ LLCoros::instance().launch("LLFacebookConnect::facebookShareCoro",
+ boost::bind(&LLFacebookConnect::facebookShareCoro, this, "/share/wall", body));
}
void LLFacebookConnect::storeInfo(const LLSD& info)
diff --git a/indra/newview/llfacebookconnect.h b/indra/newview/llfacebookconnect.h
index c157db2178..2a2cdb5499 100644
--- a/indra/newview/llfacebookconnect.h
+++ b/indra/newview/llfacebookconnect.h
@@ -30,6 +30,8 @@
#include "llsingleton.h"
#include "llimage.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
class LLEventPump;
@@ -101,6 +103,15 @@ private:
static boost::scoped_ptr<LLEventPump> sStateWatcher;
static boost::scoped_ptr<LLEventPump> sInfoWatcher;
static boost::scoped_ptr<LLEventPump> sContentWatcher;
+
+ bool testShareStatus(LLSD &results);
+ void facebookConnectCoro(std::string authCode, std::string authState);
+ void facebookConnectedCheckCoro(bool autoConnect);
+ void facebookDisconnectCoro();
+ void facebookShareCoro(std::string route, LLSD share);
+ void facebookShareImageCoro(std::string route, LLPointer<LLImageFormatted> image, std::string caption);
+ void facebookConnectInfoCoro();
+ void facebookConnectFriendsCoro();
};
#endif // LL_LLFACEBOOKCONNECT_H
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index ea39f812fd..0b76ca16a9 100755
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -40,7 +40,6 @@
#include "llappviewer.h"
#include "llbufferstream.h"
-#include "llhttpclient.h"
#include "llnotificationsutil.h"
#include "llviewercontrol.h"
#include "llworld.h"
@@ -55,6 +54,7 @@
#include "llviewershadermgr.h"
#include "llstring.h"
#include "stringize.h"
+#include "llcorehttputil.h"
#if LL_WINDOWS
#include "lldxhardware.h"
@@ -492,95 +492,70 @@ bool LLFeatureManager::loadGPUClass()
return true; // indicates that a gpu value was established
}
-
-// responder saves table into file
-class LLHTTPFeatureTableResponder : public LLHTTPClient::Responder
+void LLFeatureManager::fetchFeatureTableCoro(std::string tableName)
{
- LOG_CLASS(LLHTTPFeatureTableResponder);
-public:
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FeatureManagerHTTPTable", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLHTTPFeatureTableResponder(std::string filename) :
- mFilename(filename)
- {
- }
+ const std::string base = gSavedSettings.getString("FeatureManagerHTTPTable");
-
- virtual void completedRaw(const LLChannelDescriptors& channels,
- const LLIOPipe::buffer_ptr_t& buffer)
- {
- if (isGoodStatus())
- {
- // write to file
-
- LL_INFOS() << "writing feature table to " << mFilename << LL_ENDL;
-
- S32 file_size = buffer->countAfter(channels.in(), NULL);
- if (file_size > 0)
- {
- // read from buffer
- U8* copy_buffer = new U8[file_size];
- buffer->readAfter(channels.in(), NULL, copy_buffer, file_size);
-
- // write to file
- LLAPRFile out(mFilename, LL_APR_WB);
- out.write(copy_buffer, file_size);
- 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;
- }
- LL_WARNS() << dumpResponse() << LL_ENDL;
- }
- }
-
-private:
- std::string mFilename;
-};
-
-void fetch_feature_table(std::string table)
-{
- const std::string base = gSavedSettings.getString("FeatureManagerHTTPTable");
#if LL_WINDOWS
- std::string os_string = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
- std::string filename;
- if (os_string.find("Microsoft Windows XP") == 0)
- {
- filename = llformat(table.c_str(), "_xp", LLVersionInfo::getVersion().c_str());
- }
- else
- {
- filename = llformat(table.c_str(), "", LLVersionInfo::getVersion().c_str());
- }
+ std::string os_string = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
+ std::string filename;
+
+ if (os_string.find("Microsoft Windows XP") == 0)
+ {
+ filename = llformat(tableName.c_str(), "_xp", LLVersionInfo::getVersion().c_str());
+ }
+ else
+ {
+ filename = llformat(tableName.c_str(), "", LLVersionInfo::getVersion().c_str());
+ }
#else
- const std::string filename = llformat(table.c_str(), LLVersionInfo::getVersion().c_str());
+ const std::string filename = llformat(tableName.c_str(), LLVersionInfo::getVersion().c_str());
#endif
- const std::string url = base + "/" + filename;
+ std::string url = base + "/" + filename;
+ // testing url below
+ //url = "http://viewer-settings.secondlife.com/featuretable.2.1.1.208406.txt";
+ const std::string path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename);
- const std::string path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename);
- LL_INFOS() << "LLFeatureManager fetching " << url << " into " << path << LL_ENDL;
-
- LLHTTPClient::get(url, new LLHTTPFeatureTableResponder(path));
-}
+ LL_INFOS() << "LLFeatureManager fetching " << url << " into " << path << LL_ENDL;
+
+ LLSD result = httpAdapter->getRawAndYield(httpRequest, url);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (status)
+ { // There was a newer feature table on the server. We've grabbed it and now should write it.
+ // write to file
+ const LLSD::Binary &raw = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_RAW].asBinary();
+ LL_INFOS() << "writing feature table to " << filename << LL_ENDL;
+
+ S32 size = raw.size();
+ if (size > 0)
+ {
+ // write to file
+ LLAPRFile out(filename, LL_APR_WB);
+ out.write(raw.data(), size);
+ out.close();
+ }
+ }
+}
// fetch table(s) from a website (S3)
void LLFeatureManager::fetchHTTPTables()
{
- fetch_feature_table(FEATURE_TABLE_VER_FILENAME);
+ LLCoros::instance().launch("LLFeatureManager::fetchFeatureTableCoro",
+ boost::bind(&LLFeatureManager::fetchFeatureTableCoro, this, FEATURE_TABLE_VER_FILENAME));
}
-
void LLFeatureManager::cleanupFeatureTables()
{
std::for_each(mMaskList.begin(), mMaskList.end(), DeletePairedPointer());
diff --git a/indra/newview/llfeaturemanager.h b/indra/newview/llfeaturemanager.h
index 69078ccc21..12ea691b49 100755
--- a/indra/newview/llfeaturemanager.h
+++ b/indra/newview/llfeaturemanager.h
@@ -32,6 +32,8 @@
#include "llsingleton.h"
#include "llstring.h"
#include <map>
+#include "llcoros.h"
+#include "lleventcoro.h"
typedef enum EGPUClass
{
@@ -164,6 +166,7 @@ protected:
void initBaseMask();
+ void fetchFeatureTableCoro(std::string name);
std::map<std::string, LLFeatureList *> mMaskList;
std::set<std::string> mSkippedFeatures;
diff --git a/indra/newview/llflickrconnect.cpp b/indra/newview/llflickrconnect.cpp
index b75660ea00..83e4f19191 100644
--- a/indra/newview/llflickrconnect.cpp
+++ b/indra/newview/llflickrconnect.cpp
@@ -32,7 +32,6 @@
#include "llagent.h"
#include "llcallingcard.h" // for LLAvatarTracker
#include "llcommandhandler.h"
-#include "llhttpclient.h"
#include "llnotificationsutil.h"
#include "llurlaction.h"
#include "llimagepng.h"
@@ -43,6 +42,7 @@
#include "llfloaterwebcontent.h"
#include "llfloaterreg.h"
+#include "llcorehttputil.h"
boost::scoped_ptr<LLEventPump> LLFlickrConnect::sStateWatcher(new LLEventStream("FlickrConnectState"));
boost::scoped_ptr<LLEventPump> LLFlickrConnect::sInfoWatcher(new LLEventStream("FlickrConnectInfo"));
@@ -67,228 +67,324 @@ void toast_user_for_flickr_success()
///////////////////////////////////////////////////////////////////////////////
//
-class LLFlickrConnectResponder : public LLHTTPClient::Responder
+void LLFlickrConnect::flickrConnectCoro(std::string requestToken, std::string oauthVerifier)
{
- LOG_CLASS(LLFlickrConnectResponder);
-public:
-
- LLFlickrConnectResponder()
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+ httpOpts->setWantHeaders(true);
+ httpOpts->setFollowRedirects(false);
+
+ LLSD body;
+ if (!requestToken.empty())
+ body["request_token"] = requestToken;
+ if (!oauthVerifier.empty())
+ body["oauth_verifier"] = oauthVerifier;
+
+ setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_IN_PROGRESS);
+
+ LLSD result = httpAdapter->putAndYield(httpRequest, getFlickrConnectURL("/connection"), body, httpOpts);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ if ( status == LLCore::HttpStatus(HTTP_FOUND) )
+ {
+ std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
+ if (location.empty())
+ {
+ LL_WARNS("FlickrConnect") << "Missing Location header " << LL_ENDL;
+ }
+ else
+ {
+ openFlickrWeb(location);
+ }
+ }
+ else
+ {
+ LL_WARNS("FlickrConnect") << "Connection failed " << status.toString() << LL_ENDL;
+ setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_FAILED);
+ log_flickr_connect_error("Connect", status.getStatus(), status.toString(),
+ result.get("error_code"), result.get("error_description"));
+ }
+ }
+ else
{
- LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_IN_PROGRESS);
+ LL_DEBUGS("FlickrConnect") << "Connect successful. " << LL_ENDL;
+ setConnectionState(LLFlickrConnect::FLICKR_CONNECTED);
}
-
- /* virtual */ void httpSuccess()
- {
- LL_DEBUGS("FlickrConnect") << "Connect successful. " << dumpResponse() << LL_ENDL;
- LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTED);
- }
-
- /* virtual */ void httpFailure()
- {
- if ( HTTP_FOUND == getStatus() )
- {
- const std::string& location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
- if (location.empty())
- {
- LL_WARNS("FlickrConnect") << "Missing Location header " << dumpResponse()
- << "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
- }
- else
- {
- LLFlickrConnect::instance().openFlickrWeb(location);
- }
- }
- else
- {
- LL_WARNS("FlickrConnect") << dumpResponse() << LL_ENDL;
- LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_FAILED);
- const LLSD& content = getContent();
- log_flickr_connect_error("Connect", getStatus(), getReason(),
- content.get("error_code"), content.get("error_description"));
- }
- }
-};
+}
///////////////////////////////////////////////////////////////////////////////
//
-class LLFlickrShareResponder : public LLHTTPClient::Responder
+bool LLFlickrConnect::testShareStatus(LLSD &result)
{
- LOG_CLASS(LLFlickrShareResponder);
-public:
-
- LLFlickrShareResponder()
- {
- LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_POSTING);
- }
-
- /* virtual */ void httpSuccess()
- {
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (status)
+ return true;
+
+ if (status == LLCore::HttpStatus(HTTP_FOUND))
+ {
+ std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
+ if (location.empty())
+ {
+ LL_WARNS("FlickrConnect") << "Missing Location header " << LL_ENDL;
+ }
+ else
+ {
+ openFlickrWeb(location);
+ }
+ }
+ if (status == LLCore::HttpStatus(HTTP_NOT_FOUND))
+ {
+ LL_DEBUGS("FlickrConnect") << "Not connected. " << LL_ENDL;
+ connectToFlickr();
+ }
+ else
+ {
+ LL_WARNS("FlickrConnect") << "HTTP Status error " << status.toString() << LL_ENDL;
+ setConnectionState(LLFlickrConnect::FLICKR_POST_FAILED);
+ log_flickr_connect_error("Share", status.getStatus(), status.toString(),
+ result.get("error_code"), result.get("error_description"));
+ }
+ return false;
+}
+
+void LLFlickrConnect::flickrShareCoro(LLSD share)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+ httpOpts->setWantHeaders(true);
+ httpOpts->setFollowRedirects(false);
+
+ setConnectionState(LLFlickrConnect::FLICKR_POSTING);
+
+ LLSD result = httpAdapter->postAndYield(httpRequest, getFlickrConnectURL("/share/photo", true), share, httpOpts);
+
+ if (testShareStatus(result))
+ {
toast_user_for_flickr_success();
- LL_DEBUGS("FlickrConnect") << "Post successful. " << dumpResponse() << LL_ENDL;
- LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_POSTED);
- }
-
- /* virtual */ void httpFailure()
- {
- if ( HTTP_FOUND == getStatus() )
- {
- const std::string& location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
- if (location.empty())
- {
- LL_WARNS("FlickrConnect") << "Missing Location header " << dumpResponse()
- << "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
- }
- else
- {
- LLFlickrConnect::instance().openFlickrWeb(location);
- }
- }
- else if ( HTTP_NOT_FOUND == getStatus() )
- {
- LLFlickrConnect::instance().connectToFlickr();
- }
- else
- {
- LL_WARNS("FlickrConnect") << dumpResponse() << LL_ENDL;
- LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_POST_FAILED);
- const LLSD& content = getContent();
- log_flickr_connect_error("Share", getStatus(), getReason(),
- content.get("error_code"), content.get("error_description"));
- }
- }
-};
+ LL_DEBUGS("FlickrConnect") << "Post successful. " << LL_ENDL;
+ setConnectionState(LLFlickrConnect::FLICKR_POSTED);
+ }
+
+}
+
+void LLFlickrConnect::flickrShareImageCoro(LLPointer<LLImageFormatted> image, std::string title, std::string description, std::string tags, int safetyLevel)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+ httpOpts->setWantHeaders(true);
+ httpOpts->setFollowRedirects(false);
+
+ std::string imageFormat;
+ if (dynamic_cast<LLImagePNG*>(image.get()))
+ {
+ imageFormat = "png";
+ }
+ else if (dynamic_cast<LLImageJPEG*>(image.get()))
+ {
+ imageFormat = "jpg";
+ }
+ else
+ {
+ LL_WARNS() << "Image to upload is not a PNG or JPEG" << LL_ENDL;
+ return;
+ }
+
+ // All this code is mostly copied from LLWebProfile::post()
+ const std::string boundary = "----------------------------0123abcdefab";
+
+ std::string contentType = "multipart/form-data; boundary=" + boundary;
+ httpHeaders->append("Content-Type", contentType.c_str());
+
+ LLCore::BufferArray::ptr_t raw = LLCore::BufferArray::ptr_t(new LLCore::BufferArray()); //
+ LLCore::BufferArrayStream body(raw.get());
+
+ // *NOTE: The order seems to matter.
+ body << "--" << boundary << "\r\n"
+ << "Content-Disposition: form-data; name=\"title\"\r\n\r\n"
+ << title << "\r\n";
+
+ body << "--" << boundary << "\r\n"
+ << "Content-Disposition: form-data; name=\"description\"\r\n\r\n"
+ << description << "\r\n";
+
+ body << "--" << boundary << "\r\n"
+ << "Content-Disposition: form-data; name=\"tags\"\r\n\r\n"
+ << tags << "\r\n";
+
+ body << "--" << boundary << "\r\n"
+ << "Content-Disposition: form-data; name=\"safety_level\"\r\n\r\n"
+ << safetyLevel << "\r\n";
+
+ body << "--" << boundary << "\r\n"
+ << "Content-Disposition: form-data; name=\"image\"; filename=\"Untitled." << imageFormat << "\"\r\n"
+ << "Content-Type: image/" << imageFormat << "\r\n\r\n";
+
+ // Insert the image data.
+ // *FIX: Treating this as a string will probably screw it up ...
+ U8* image_data = image->getData();
+ for (S32 i = 0; i < image->getDataSize(); ++i)
+ {
+ body << image_data[i];
+ }
+
+ body << "\r\n--" << boundary << "--\r\n";
+
+ LLSD result = httpAdapter->postAndYield(httpRequest, getFlickrConnectURL("/share/photo", true), raw, httpOpts, httpHeaders);
+
+ if (testShareStatus(result))
+ {
+ toast_user_for_flickr_success();
+ LL_DEBUGS("FlickrConnect") << "Post successful. " << LL_ENDL;
+ setConnectionState(LLFlickrConnect::FLICKR_POSTED);
+ }
+}
///////////////////////////////////////////////////////////////////////////////
//
-class LLFlickrDisconnectResponder : public LLHTTPClient::Responder
+void LLFlickrConnect::flickrDisconnectCoro()
{
- LOG_CLASS(LLFlickrDisconnectResponder);
-public:
-
- LLFlickrDisconnectResponder()
- {
- LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_DISCONNECTING);
- }
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
- void setUserDisconnected()
- {
- // Clear data
- LLFlickrConnect::instance().clearInfo();
+ setConnectionState(LLFlickrConnect::FLICKR_DISCONNECTING);
+ httpOpts->setFollowRedirects(false);
- //Notify state change
- LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_NOT_CONNECTED);
- }
+ LLSD result = httpAdapter->deleteAndYield(httpRequest, getFlickrConnectURL("/connection"), httpOpts);
- /* virtual */ void httpSuccess()
- {
- LL_DEBUGS("FlickrConnect") << "Disconnect successful. " << dumpResponse() << LL_ENDL;
- setUserDisconnected();
- }
-
- /* virtual */ void httpFailure()
- {
- //User not found so already disconnected
- if ( HTTP_NOT_FOUND == getStatus() )
- {
- LL_DEBUGS("FlickrConnect") << "Already disconnected. " << dumpResponse() << LL_ENDL;
- setUserDisconnected();
- }
- else
- {
- LL_WARNS("FlickrConnect") << dumpResponse() << LL_ENDL;
- LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_DISCONNECT_FAILED);
- const LLSD& content = getContent();
- log_flickr_connect_error("Disconnect", getStatus(), getReason(),
- content.get("error_code"), content.get("error_description"));
- }
- }
-};
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status && (status != LLCore::HttpStatus(HTTP_NOT_FOUND)))
+ {
+ LL_WARNS("FlickrConnect") << "Disconnect failed!" << LL_ENDL;
+ setConnectionState(LLFlickrConnect::FLICKR_DISCONNECT_FAILED);
+
+ log_flickr_connect_error("Disconnect", status.getStatus(), status.toString(),
+ result.get("error_code"), result.get("error_description"));
+ }
+ else
+ {
+ LL_DEBUGS("FlickrConnect") << "Disconnect successful. " << LL_ENDL;
+ clearInfo();
+ setConnectionState(LLFlickrConnect::FLICKR_NOT_CONNECTED);
+ }
+}
///////////////////////////////////////////////////////////////////////////////
//
-class LLFlickrConnectedResponder : public LLHTTPClient::Responder
+void LLFlickrConnect::flickrConnectedCoro(bool autoConnect)
{
- LOG_CLASS(LLFlickrConnectedResponder);
-public:
-
- LLFlickrConnectedResponder(bool auto_connect) : mAutoConnect(auto_connect)
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+ setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_IN_PROGRESS);
+
+ httpOpts->setFollowRedirects(false);
+
+ LLSD result = httpAdapter->getAndYield(httpRequest, getFlickrConnectURL("/connection", true), httpOpts);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
{
- LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_IN_PROGRESS);
+ if (status == LLCore::HttpStatus(HTTP_NOT_FOUND))
+ {
+ LL_DEBUGS("FlickrConnect") << "Not connected. " << LL_ENDL;
+ if (autoConnect)
+ {
+ connectToFlickr();
+ }
+ else
+ {
+ setConnectionState(LLFlickrConnect::FLICKR_NOT_CONNECTED);
+ }
+ }
+ else
+ {
+ LL_WARNS("FlickrConnect") << "Failed to test connection:" << status.toTerseString() << LL_ENDL;
+
+ setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_FAILED);
+ log_flickr_connect_error("Connected", status.getStatus(), status.toString(),
+ result.get("error_code"), result.get("error_description"));
+ }
}
-
- /* virtual */ void httpSuccess()
- {
- LL_DEBUGS("FlickrConnect") << "Connect successful. " << dumpResponse() << LL_ENDL;
- LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTED);
- }
-
- /* virtual */ void httpFailure()
- {
- // show the facebook login page if not connected yet
- if ( HTTP_NOT_FOUND == getStatus() )
- {
- LL_DEBUGS("FlickrConnect") << "Not connected. " << dumpResponse() << LL_ENDL;
- if (mAutoConnect)
- {
- LLFlickrConnect::instance().connectToFlickr();
- }
- else
- {
- LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_NOT_CONNECTED);
- }
- }
- else
- {
- LL_WARNS("FlickrConnect") << dumpResponse() << LL_ENDL;
- LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_FAILED);
- const LLSD& content = getContent();
- log_flickr_connect_error("Connected", getStatus(), getReason(),
- content.get("error_code"), content.get("error_description"));
- }
- }
-
-private:
- bool mAutoConnect;
-};
+ else
+ {
+ LL_DEBUGS("FlickrConnect") << "Connect successful. " << LL_ENDL;
+ setConnectionState(LLFlickrConnect::FLICKR_CONNECTED);
+ }
+
+}
///////////////////////////////////////////////////////////////////////////////
//
-class LLFlickrInfoResponder : public LLHTTPClient::Responder
+void LLFlickrConnect::flickrInfoCoro()
{
- LOG_CLASS(LLFlickrInfoResponder);
-public:
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
- /* virtual */ void httpSuccess()
- {
- LL_INFOS("FlickrConnect") << "Flickr: Info received" << LL_ENDL;
- LL_DEBUGS("FlickrConnect") << "Getting Flickr info successful. " << dumpResponse() << LL_ENDL;
- LLFlickrConnect::instance().storeInfo(getContent());
- }
-
- /* virtual */ void httpFailure()
- {
- if ( HTTP_FOUND == getStatus() )
- {
- const std::string& location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
- if (location.empty())
- {
- LL_WARNS("FlickrConnect") << "Missing Location header " << dumpResponse()
- << "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
- }
- else
- {
- LLFlickrConnect::instance().openFlickrWeb(location);
- }
- }
- else
- {
- LL_WARNS("FlickrConnect") << dumpResponse() << LL_ENDL;
- const LLSD& content = getContent();
- log_flickr_connect_error("Info", getStatus(), getReason(),
- content.get("error_code"), content.get("error_description"));
- }
- }
-};
+ httpOpts->setWantHeaders(true);
+ httpOpts->setFollowRedirects(false);
+
+ LLSD result = httpAdapter->getAndYield(httpRequest, getFlickrConnectURL("/info", true), httpOpts);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (status == LLCore::HttpStatus(HTTP_FOUND))
+ {
+ std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
+ if (location.empty())
+ {
+ LL_WARNS("FlickrConnect") << "Missing Location header " << LL_ENDL;
+ }
+ else
+ {
+ openFlickrWeb(location);
+ }
+ }
+ else if (!status)
+ {
+ LL_WARNS("FlickrConnect") << "Flickr Info failed: " << status.toString() << LL_ENDL;
+ log_flickr_connect_error("Info", status.getStatus(), status.toString(),
+ result.get("error_code"), result.get("error_description"));
+ }
+ else
+ {
+ LL_INFOS("FlickrConnect") << "Flickr: Info received" << LL_ENDL;
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ storeInfo(result);
+ }
+}
///////////////////////////////////////////////////////////////////////////////
//
@@ -341,36 +437,28 @@ std::string LLFlickrConnect::getFlickrConnectURL(const std::string& route, bool
void LLFlickrConnect::connectToFlickr(const std::string& request_token, const std::string& oauth_verifier)
{
- LLSD body;
- if (!request_token.empty())
- body["request_token"] = request_token;
- if (!oauth_verifier.empty())
- body["oauth_verifier"] = oauth_verifier;
-
- LLHTTPClient::put(getFlickrConnectURL("/connection"), body, new LLFlickrConnectResponder());
+ LLCoros::instance().launch("LLFlickrConnect::flickrConnectCoro",
+ boost::bind(&LLFlickrConnect::flickrConnectCoro, this, request_token, oauth_verifier));
}
void LLFlickrConnect::disconnectFromFlickr()
{
- LLHTTPClient::del(getFlickrConnectURL("/connection"), new LLFlickrDisconnectResponder());
+ LLCoros::instance().launch("LLFlickrConnect::flickrDisconnectCoro",
+ boost::bind(&LLFlickrConnect::flickrDisconnectCoro, this));
}
void LLFlickrConnect::checkConnectionToFlickr(bool auto_connect)
{
- const bool follow_redirects = false;
- const F32 timeout = HTTP_REQUEST_EXPIRY_SECS;
- LLHTTPClient::get(getFlickrConnectURL("/connection", true), new LLFlickrConnectedResponder(auto_connect),
- LLSD(), timeout, follow_redirects);
+ LLCoros::instance().launch("LLFlickrConnect::flickrConnectedCoro",
+ boost::bind(&LLFlickrConnect::flickrConnectedCoro, this, auto_connect));
}
void LLFlickrConnect::loadFlickrInfo()
{
if(mRefreshInfo)
{
- const bool follow_redirects = false;
- const F32 timeout = HTTP_REQUEST_EXPIRY_SECS;
- LLHTTPClient::get(getFlickrConnectURL("/info", true), new LLFlickrInfoResponder(),
- LLSD(), timeout, follow_redirects);
+ LLCoros::instance().launch("LLFlickrConnect::flickrInfoCoro",
+ boost::bind(&LLFlickrConnect::flickrInfoCoro, this));
}
}
@@ -382,74 +470,17 @@ void LLFlickrConnect::uploadPhoto(const std::string& image_url, const std::strin
body["description"] = description;
body["tags"] = tags;
body["safety_level"] = safety_level;
-
- // Note: we can use that route for different publish action. We should be able to use the same responder.
- LLHTTPClient::post(getFlickrConnectURL("/share/photo", true), body, new LLFlickrShareResponder());
+
+ LLCoros::instance().launch("LLFlickrConnect::flickrShareCoro",
+ boost::bind(&LLFlickrConnect::flickrShareCoro, this, body));
}
void LLFlickrConnect::uploadPhoto(LLPointer<LLImageFormatted> image, const std::string& title, const std::string& description, const std::string& tags, int safety_level)
{
- std::string imageFormat;
- if (dynamic_cast<LLImagePNG*>(image.get()))
- {
- imageFormat = "png";
- }
- else if (dynamic_cast<LLImageJPEG*>(image.get()))
- {
- imageFormat = "jpg";
- }
- else
- {
- LL_WARNS() << "Image to upload is not a PNG or JPEG" << LL_ENDL;
- return;
- }
-
- // All this code is mostly copied from LLWebProfile::post()
- const std::string boundary = "----------------------------0123abcdefab";
-
- LLSD headers;
- headers["Content-Type"] = "multipart/form-data; boundary=" + boundary;
-
- std::ostringstream body;
-
- // *NOTE: The order seems to matter.
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"title\"\r\n\r\n"
- << title << "\r\n";
-
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"description\"\r\n\r\n"
- << description << "\r\n";
-
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"tags\"\r\n\r\n"
- << tags << "\r\n";
-
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"safety_level\"\r\n\r\n"
- << safety_level << "\r\n";
-
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"image\"; filename=\"Untitled." << imageFormat << "\"\r\n"
- << "Content-Type: image/" << imageFormat << "\r\n\r\n";
-
- // Insert the image data.
- // *FIX: Treating this as a string will probably screw it up ...
- U8* image_data = image->getData();
- for (S32 i = 0; i < image->getDataSize(); ++i)
- {
- body << image_data[i];
- }
-
- body << "\r\n--" << boundary << "--\r\n";
- // postRaw() takes ownership of the buffer and releases it later.
- size_t size = body.str().size();
- U8 *data = new U8[size];
- memcpy(data, body.str().data(), size);
-
- // Note: we can use that route for different publish action. We should be able to use the same responder.
- LLHTTPClient::postRaw(getFlickrConnectURL("/share/photo", true), data, size, new LLFlickrShareResponder(), headers);
+ LLCoros::instance().launch("LLFlickrConnect::flickrShareImageCoro",
+ boost::bind(&LLFlickrConnect::flickrShareImageCoro, this, image,
+ title, description, tags, safety_level));
}
void LLFlickrConnect::storeInfo(const LLSD& info)
diff --git a/indra/newview/llflickrconnect.h b/indra/newview/llflickrconnect.h
index b127e6e104..0155804da0 100644
--- a/indra/newview/llflickrconnect.h
+++ b/indra/newview/llflickrconnect.h
@@ -30,6 +30,8 @@
#include "llsingleton.h"
#include "llimage.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
class LLEventPump;
@@ -93,6 +95,15 @@ private:
static boost::scoped_ptr<LLEventPump> sStateWatcher;
static boost::scoped_ptr<LLEventPump> sInfoWatcher;
static boost::scoped_ptr<LLEventPump> sContentWatcher;
+
+ bool testShareStatus(LLSD &result);
+ void flickrConnectCoro(std::string requestToken, std::string oauthVerifier);
+ void flickrShareCoro(LLSD share);
+ void flickrShareImageCoro(LLPointer<LLImageFormatted> image, std::string title, std::string description, std::string tags, int safetyLevel);
+ void flickrDisconnectCoro();
+ void flickrConnectedCoro(bool autoConnect);
+ void flickrInfoCoro();
+
};
#endif // LL_LLFLICKRCONNECT_H
diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index b342d8fdf3..f58a5881a8 100755
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -61,6 +61,7 @@
#include "stringize.h"
#include "llsdutil_math.h"
#include "lleventapi.h"
+#include "llcorehttputil.h"
#if LL_WINDOWS
#include "lldxhardware.h"
@@ -70,18 +71,6 @@ extern LLMemoryInfo gSysMemory;
extern U32 gPacketsIn;
///----------------------------------------------------------------------------
-/// Class LLServerReleaseNotesURLFetcher
-///----------------------------------------------------------------------------
-class LLServerReleaseNotesURLFetcher : public LLHTTPClient::Responder
-{
- LOG_CLASS(LLServerReleaseNotesURLFetcher);
-public:
- static void startFetch();
-private:
- /* virtual */ void httpCompleted();
-};
-
-///----------------------------------------------------------------------------
/// Class LLFloaterAbout
///----------------------------------------------------------------------------
class LLFloaterAbout
@@ -102,6 +91,9 @@ public:
private:
void setSupportText(const std::string& server_release_notes_url);
+
+ static void startFetchServerReleaseNotes();
+ static void handleServerReleaseNotes(LLSD results);
};
@@ -138,7 +130,7 @@ BOOL LLFloaterAbout::postBuild()
{
// start fetching server release notes URL
setSupportText(LLTrans::getString("RetrievingData"));
- LLServerReleaseNotesURLFetcher::startFetch();
+ startFetchServerReleaseNotes();
}
else // not logged in
{
@@ -201,6 +193,50 @@ LLSD LLFloaterAbout::getInfo()
return LLAppViewer::instance()->getViewerInfo();
}
+/*static*/
+void LLFloaterAbout::startFetchServerReleaseNotes()
+{
+ LLViewerRegion* region = gAgent.getRegion();
+ if (!region) return;
+
+ // We cannot display the URL returned by the ServerReleaseNotes capability
+ // because opening it in an external browser will trigger a warning about untrusted
+ // SSL certificate.
+ // So we query the URL ourselves, expecting to find
+ // an URL suitable for external browsers in the "Location:" HTTP header.
+ std::string cap_url = region->getCapability("ServerReleaseNotes");
+
+ LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpGet(cap_url,
+ &LLFloaterAbout::handleServerReleaseNotes, &LLFloaterAbout::handleServerReleaseNotes);
+
+}
+
+/*static*/
+void LLFloaterAbout::handleServerReleaseNotes(LLSD results)
+{
+ LLFloaterAbout* floater_about = LLFloaterReg::getTypedInstance<LLFloaterAbout>("sl_about");
+ if (floater_about)
+ {
+ LLSD http_headers;
+ if (results.has(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS))
+ {
+ LLSD http_results = results[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ http_headers = http_results[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
+ }
+ else
+ {
+ http_headers = results[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
+ }
+
+ std::string location = http_headers[HTTP_IN_HEADER_LOCATION].asString();
+ if (location.empty())
+ {
+ location = LLTrans::getString("ErrorFetchingServerReleaseNotesURL");
+ }
+ LLAppViewer::instance()->setServerReleaseNotesURL(location);
+ }
+}
+
class LLFloaterAboutListener: public LLEventAPI
{
public:
@@ -264,40 +300,3 @@ void LLFloaterAboutUtil::registerFloater()
&LLFloaterReg::build<LLFloaterAbout>);
}
-
-///----------------------------------------------------------------------------
-/// Class LLServerReleaseNotesURLFetcher implementation
-///----------------------------------------------------------------------------
-// static
-void LLServerReleaseNotesURLFetcher::startFetch()
-{
- LLViewerRegion* region = gAgent.getRegion();
- if (!region) return;
-
- // We cannot display the URL returned by the ServerReleaseNotes capability
- // because opening it in an external browser will trigger a warning about untrusted
- // SSL certificate.
- // So we query the URL ourselves, expecting to find
- // an URL suitable for external browsers in the "Location:" HTTP header.
- std::string cap_url = region->getCapability("ServerReleaseNotes");
- LLHTTPClient::get(cap_url, new LLServerReleaseNotesURLFetcher);
-}
-
-// virtual
-void LLServerReleaseNotesURLFetcher::httpCompleted()
-{
- LL_DEBUGS("ServerReleaseNotes") << dumpResponse()
- << " [headers:" << getResponseHeaders() << "]" << LL_ENDL;
-
- LLFloaterAbout* floater_about = LLFloaterReg::getTypedInstance<LLFloaterAbout>("sl_about");
- if (floater_about)
- {
- std::string location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
- if (location.empty())
- {
- location = LLTrans::getString("ErrorFetchingServerReleaseNotesURL");
- }
- LLAppViewer::instance()->setServerReleaseNotesURL(location);
- }
-}
-
diff --git a/indra/newview/llfloaterauction.cpp b/indra/newview/llfloaterauction.cpp
index b661fed276..56619e818a 100755
--- a/indra/newview/llfloaterauction.cpp
+++ b/indra/newview/llfloaterauction.cpp
@@ -57,6 +57,7 @@
#include "llsdutil.h"
#include "llsdutil_math.h"
#include "lltrans.h"
+#include "llcorehttputil.h"
///----------------------------------------------------------------------------
/// Local function declarations, constants, enums, and typedefs
@@ -361,7 +362,10 @@ void LLFloaterAuction::doResetParcel()
LL_INFOS() << "Sending parcel update to reset for auction via capability to: "
<< mParcelUpdateCapUrl << LL_ENDL;
- LLHTTPClient::post(mParcelUpdateCapUrl, body, new LLHTTPClient::Responder());
+
+ LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(mParcelUpdateCapUrl, body,
+ "Parcel reset for auction",
+ "Parcel not set for auction.");
// Send a message to clear the object return time
LLMessageSystem *msg = gMessageSystem;
@@ -490,7 +494,10 @@ void LLFloaterAuction::doSellToAnyone()
LL_INFOS() << "Sending parcel update to sell to anyone for L$1 via capability to: "
<< mParcelUpdateCapUrl << LL_ENDL;
- LLHTTPClient::post(mParcelUpdateCapUrl, body, new LLHTTPClient::Responder());
+
+ LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(mParcelUpdateCapUrl, body,
+ "Parcel set as sell to everyone.",
+ "Parcel sell to everyone failed.");
// clean up floater, and get out
cleanupAndClose();
diff --git a/indra/newview/llfloaterautoreplacesettings.cpp b/indra/newview/llfloaterautoreplacesettings.cpp
index 6e56e929df..5830f2f711 100755
--- a/indra/newview/llfloaterautoreplacesettings.cpp
+++ b/indra/newview/llfloaterautoreplacesettings.cpp
@@ -36,7 +36,6 @@
#include "llcolorswatch.h"
#include "llcombobox.h"
#include "llview.h"
-#include "llhttpclient.h"
#include "llbufferstream.h"
#include "llcheckboxctrl.h"
#include "llviewercontrol.h"
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index 566a3c9cd3..2824038f77 100755
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -42,7 +42,6 @@
#include "llavatarnamecache.h" // IDEVO
#include "llbutton.h"
#include "llcachename.h"
-#include "llhttpclient.h" // IDEVO
#include "lllineeditor.h"
#include "llscrolllistctrl.h"
#include "llscrolllistitem.h"
@@ -52,6 +51,7 @@
#include "llfocusmgr.h"
#include "lldraghandle.h"
#include "message.h"
+#include "llcorehttputil.h"
//#include "llsdserialize.h"
@@ -456,39 +456,33 @@ BOOL LLFloaterAvatarPicker::visibleItemsSelected() const
return FALSE;
}
-class LLAvatarPickerResponder : public LLHTTPClient::Responder
+/*static*/
+void LLFloaterAvatarPicker::findCoro(std::string url, LLUUID queryID, std::string name)
{
- LOG_CLASS(LLAvatarPickerResponder);
-public:
- LLUUID mQueryID;
- std::string mName;
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("genericPostCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLAvatarPickerResponder(const LLUUID& id, const std::string& name) : mQueryID(id), mName(name) { }
+ LL_INFOS("HttpCoroutineAdapter", "genericPostCoro") << "Generic POST for " << url << LL_ENDL;
-protected:
- /*virtual*/ void httpCompleted()
- {
- //std::ostringstream ss;
- //LLSDSerialize::toPrettyXML(content, ss);
- //LL_INFOS() << ss.str() << LL_ENDL;
+ LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (status || (status == LLCore::HttpStatus(HTTP_BAD_REQUEST)))
+ {
+ LLFloaterAvatarPicker* floater =
+ LLFloaterReg::findTypedInstance<LLFloaterAvatarPicker>("avatar_picker", name);
+ if (floater)
+ {
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ floater->processResponse(queryID, result);
+ }
+ }
+}
- // in case of invalid characters, the avatar picker returns a 400
- // just set it to process so it displays 'not found'
- if (isGoodStatus() || getStatus() == HTTP_BAD_REQUEST)
- {
- LLFloaterAvatarPicker* floater =
- LLFloaterReg::findTypedInstance<LLFloaterAvatarPicker>("avatar_picker", mName);
- if (floater)
- {
- floater->processResponse(mQueryID, getContent());
- }
- }
- else
- {
- LL_WARNS() << "avatar picker failed " << dumpResponse() << LL_ENDL;
- }
- }
-};
void LLFloaterAvatarPicker::find()
{
@@ -517,7 +511,9 @@ void LLFloaterAvatarPicker::find()
std::replace(text.begin(), text.end(), '.', ' ');
url += LLURI::escape(text);
LL_INFOS() << "avatar picker " << url << LL_ENDL;
- LLHTTPClient::get(url, new LLAvatarPickerResponder(mQueryID, getKey().asString()));
+
+ LLCoros::instance().launch("LLFloaterAvatarPicker::findCoro",
+ boost::bind(&LLFloaterAvatarPicker::findCoro, url, mQueryID, getKey().asString()));
}
else
{
diff --git a/indra/newview/llfloateravatarpicker.h b/indra/newview/llfloateravatarpicker.h
index ed3e51c56f..fbee61b054 100755
--- a/indra/newview/llfloateravatarpicker.h
+++ b/indra/newview/llfloateravatarpicker.h
@@ -28,6 +28,8 @@
#define LLFLOATERAVATARPICKER_H
#include "llfloater.h"
+#include "lleventcoro.h"
+#include "llcoros.h"
#include <vector>
@@ -84,6 +86,7 @@ private:
void populateFriend();
BOOL visibleItemsSelected() const; // Returns true if any items in the current tab are selected.
+ static void findCoro(std::string url, LLUUID mQueryID, std::string mName);
void find();
void setAllowMultiple(BOOL allow_multiple);
LLScrollListCtrl* getActiveList();
diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp
index 669ffa7c59..e5df417ca9 100755
--- a/indra/newview/llfloaterbvhpreview.cpp
+++ b/indra/newview/llfloaterbvhpreview.cpp
@@ -992,20 +992,16 @@ void LLFloaterBvhPreview::onBtnOK(void* userdata)
{
std::string name = floaterp->getChild<LLUICtrl>("name_form")->getValue().asString();
std::string desc = floaterp->getChild<LLUICtrl>("description_form")->getValue().asString();
- LLAssetStorage::LLStoreAssetCallback callback = NULL;
S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
- void *userdata = NULL;
- upload_new_resource(floaterp->mTransactionID, // tid
- LLAssetType::AT_ANIMATION,
- name,
- desc,
- 0,
- LLFolderType::FT_NONE,
- LLInventoryType::IT_ANIMATION,
- LLFloaterPerms::getNextOwnerPerms("Uploads"), LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"),
- name,
- callback, expected_upload_cost, userdata);
+ LLResourceUploadInfo::ptr_t assetUpdloadInfo(new LLResourceUploadInfo(
+ floaterp->mTransactionID, LLAssetType::AT_ANIMATION,
+ name, desc, 0,
+ LLFolderType::FT_NONE, LLInventoryType::IT_ANIMATION,
+ LLFloaterPerms::getNextOwnerPerms("Uploads"), LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"),
+ expected_upload_cost));
+
+ upload_new_resource(assetUpdloadInfo);
}
else
{
diff --git a/indra/newview/llfloaterdisplayname.cpp b/indra/newview/llfloaterdisplayname.cpp
deleted file mode 100755
index 596e8c0dbe..0000000000
--- a/indra/newview/llfloaterdisplayname.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-/**
- * @file llfloaterdisplayname.cpp
- * @author Leyla Farazha
- * @brief Implementation of the LLFloaterDisplayName class.
- *
- * $LicenseInfo:firstyear=2002&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 "llviewerprecompiledheaders.h"
-#include "llfloaterreg.h"
-#include "llfloater.h"
-
-#include "llnotificationsutil.h"
-#include "llviewerdisplayname.h"
-
-#include "llnotifications.h"
-#include "llfloaterdisplayname.h"
-#include "llavatarnamecache.h"
-
-#include "llagent.h"
-
-
-class LLFloaterDisplayName : public LLFloater
-{
-public:
- LLFloaterDisplayName(const LLSD& key);
- virtual ~LLFloaterDisplayName() { }
- /*virtual*/ BOOL postBuild();
- void onSave();
- void onReset();
- void onCancel();
- /*virtual*/ void onOpen(const LLSD& key);
-
-private:
-
- void onCacheSetName(bool success,
- const std::string& reason,
- const LLSD& content);
-};
-
-LLFloaterDisplayName::LLFloaterDisplayName(const LLSD& key) :
- LLFloater(key)
-{
-}
-
-void LLFloaterDisplayName::onOpen(const LLSD& key)
-{
- getChild<LLUICtrl>("display_name_editor")->clear();
- getChild<LLUICtrl>("display_name_confirm")->clear();
-
- LLAvatarName av_name;
- LLAvatarNameCache::get(gAgent.getID(), &av_name);
-
- F64 now_secs = LLDate::now().secondsSinceEpoch();
-
- if (now_secs < av_name.mNextUpdate)
- {
- // ...can't update until some time in the future
- F64 next_update_local_secs =
- av_name.mNextUpdate - LLStringOps::getLocalTimeOffset();
- LLDate next_update_local(next_update_local_secs);
- // display as "July 18 12:17 PM"
- std::string next_update_string =
- next_update_local.toHTTPDateString("%B %d %I:%M %p");
- getChild<LLUICtrl>("lockout_text")->setTextArg("[TIME]", next_update_string);
- getChild<LLUICtrl>("lockout_text")->setVisible(true);
- getChild<LLUICtrl>("save_btn")->setEnabled(false);
- getChild<LLUICtrl>("display_name_editor")->setEnabled(false);
- getChild<LLUICtrl>("display_name_confirm")->setEnabled(false);
- getChild<LLUICtrl>("cancel_btn")->setFocus(TRUE);
-
- }
- else
- {
- getChild<LLUICtrl>("lockout_text")->setVisible(false);
- getChild<LLUICtrl>("save_btn")->setEnabled(true);
- getChild<LLUICtrl>("display_name_editor")->setEnabled(true);
- getChild<LLUICtrl>("display_name_confirm")->setEnabled(true);
-
- }
-}
-
-BOOL LLFloaterDisplayName::postBuild()
-{
- getChild<LLUICtrl>("reset_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onReset, this));
- getChild<LLUICtrl>("cancel_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onCancel, this));
- getChild<LLUICtrl>("save_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onSave, this));
-
- center();
-
- return TRUE;
-}
-
-void LLFloaterDisplayName::onCacheSetName(bool success,
- const std::string& reason,
- const LLSD& content)
-{
- if (success)
- {
- // Inform the user that the change took place, but will take a while
- // to percolate.
- LLSD args;
- args["DISPLAY_NAME"] = content["display_name"];
- LLNotificationsUtil::add("SetDisplayNameSuccess", args);
- return;
- }
-
- // Request failed, notify the user
- std::string error_tag = content["error_tag"].asString();
- LL_INFOS() << "set name failure error_tag " << error_tag << LL_ENDL;
-
- // We might have a localized string for this message
- // error_args will usually be empty from the server.
- if (!error_tag.empty()
- && LLNotifications::getInstance()->templateExists(error_tag))
- {
- LLNotificationsUtil::add(error_tag);
- return;
- }
-
- // The server error might have a localized message for us
- std::string lang_code = LLUI::getLanguage();
- LLSD error_desc = content["error_description"];
- if (error_desc.has( lang_code ))
- {
- LLSD args;
- args["MESSAGE"] = error_desc[lang_code].asString();
- LLNotificationsUtil::add("GenericAlert", args);
- return;
- }
-
- // No specific error, throw a generic one
- LLNotificationsUtil::add("SetDisplayNameFailedGeneric");
-}
-
-void LLFloaterDisplayName::onCancel()
-{
- setVisible(false);
-}
-
-void LLFloaterDisplayName::onReset()
-{
- if (LLAvatarNameCache::hasNameLookupURL())
- {
- LLViewerDisplayName::set("",boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3));
- }
- else
- {
- LLNotificationsUtil::add("SetDisplayNameFailedGeneric");
- }
-
- setVisible(false);
-}
-
-
-void LLFloaterDisplayName::onSave()
-{
- std::string display_name_utf8 = getChild<LLUICtrl>("display_name_editor")->getValue().asString();
- std::string display_name_confirm = getChild<LLUICtrl>("display_name_confirm")->getValue().asString();
-
- if (display_name_utf8.compare(display_name_confirm))
- {
- LLNotificationsUtil::add("SetDisplayNameMismatch");
- return;
- }
-
- const U32 DISPLAY_NAME_MAX_LENGTH = 31; // characters, not bytes
- LLWString display_name_wstr = utf8string_to_wstring(display_name_utf8);
- if (display_name_wstr.size() > DISPLAY_NAME_MAX_LENGTH)
- {
- LLSD args;
- args["LENGTH"] = llformat("%d", DISPLAY_NAME_MAX_LENGTH);
- LLNotificationsUtil::add("SetDisplayNameFailedLength", args);
- return;
- }
-
- if (LLAvatarNameCache::hasNameLookupURL())
- {
- LLViewerDisplayName::set(display_name_utf8,boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3));
- }
- else
- {
- LLNotificationsUtil::add("SetDisplayNameFailedGeneric");
- }
-
- setVisible(false);
-}
-
-
-//////////////////////////////////////////////////////////////////////////////
-// LLInspectObjectUtil
-//////////////////////////////////////////////////////////////////////////////
-void LLFloaterDisplayNameUtil::registerFloater()
-{
- LLFloaterReg::add("display_name", "floater_display_name.xml",
- &LLFloaterReg::build<LLFloaterDisplayName>);
-}
diff --git a/indra/newview/llfloaterdisplayname.h b/indra/newview/llfloaterdisplayname.h
deleted file mode 100755
index a00bf56712..0000000000
--- a/indra/newview/llfloaterdisplayname.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * @file llfloaterdisplayname.h
- *
- * $LicenseInfo:firstyear=2009&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 LLFLOATERDISPLAYNAME_H
-#define LLFLOATERDISPLAYNAME_H
-
-
-namespace LLFloaterDisplayNameUtil
-{
- // Register with LLFloaterReg
- void registerFloater();
-}
-
-
-
-#endif
diff --git a/indra/newview/llfloaterhoverheight.cpp b/indra/newview/llfloaterhoverheight.cpp
index 8908626de6..003a22fa04 100755
--- a/indra/newview/llfloaterhoverheight.cpp
+++ b/indra/newview/llfloaterhoverheight.cpp
@@ -31,7 +31,6 @@
#include "llsliderctrl.h"
#include "llviewercontrol.h"
#include "llsdserialize.h"
-#include "llhttpclient.h"
#include "llagent.h"
#include "llviewerregion.h"
#include "llvoavatarself.h"
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index fc7fcf3ab9..6623ce0f80 100755
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -41,7 +41,6 @@
#include "llchicletbar.h"
#include "lldonotdisturbnotificationstorage.h"
#include "llfloaterreg.h"
-#include "llhttpclient.h"
#include "llfloateravatarpicker.h"
#include "llfloaterimcontainer.h" // to replace separate IM Floaters with multifloater container
#include "llinventoryfunctions.h"
@@ -62,6 +61,7 @@
#include "llviewerchat.h"
#include "llnotificationmanager.h"
#include "llautoreplace.h"
+#include "llcorehttputil.h"
const F32 ME_TYPING_TIMEOUT = 4.0f;
const F32 OTHER_TYPING_TIMEOUT = 9.0f;
@@ -1178,26 +1178,6 @@ BOOL LLFloaterIMSession::isInviteAllowed() const
|| mIsP2PChat);
}
-class LLSessionInviteResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(LLSessionInviteResponder);
-public:
- LLSessionInviteResponder(const LLUUID& session_id)
- {
- mSessionID = session_id;
- }
-
-protected:
- void httpFailure()
- {
- LL_WARNS() << "Error inviting all agents to session " << dumpResponse() << LL_ENDL;
- //throw something back to the viewer here?
- }
-
-private:
- LLUUID mSessionID;
-};
-
BOOL LLFloaterIMSession::inviteToSession(const uuid_vec_t& ids)
{
LLViewerRegion* region = gAgent.getRegion();
@@ -1221,7 +1201,9 @@ BOOL LLFloaterIMSession::inviteToSession(const uuid_vec_t& ids)
}
data["method"] = "invite";
data["session-id"] = mSessionID;
- LLHTTPClient::post(url, data,new LLSessionInviteResponder(mSessionID));
+
+ LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, data,
+ "Session invite sent", "Session invite failed");
}
else
{
diff --git a/indra/newview/llfloatermodeluploadbase.cpp b/indra/newview/llfloatermodeluploadbase.cpp
index 22a8ac4705..e2f84fd990 100755
--- a/indra/newview/llfloatermodeluploadbase.cpp
+++ b/indra/newview/llfloatermodeluploadbase.cpp
@@ -30,6 +30,7 @@
#include "llagent.h"
#include "llviewerregion.h"
#include "llnotificationsutil.h"
+#include "llcorehttputil.h"
LLFloaterModelUploadBase::LLFloaterModelUploadBase(const LLSD& key)
:LLFloater(key),
@@ -47,7 +48,8 @@ void LLFloaterModelUploadBase::requestAgentUploadPermissions()
LL_INFOS()<< typeid(*this).name()
<< "::requestAgentUploadPermissions() requesting for upload model permissions from: "
<< url << LL_ENDL;
- LLHTTPClient::get(url, new LLUploadModelPermissionsResponder(getPermObserverHandle()));
+ LLCoros::instance().launch("LLFloaterModelUploadBase::requestAgentUploadPermissionsCoro",
+ boost::bind(&LLFloaterModelUploadBase::requestAgentUploadPermissionsCoro, this, url, getPermObserverHandle()));
}
else
{
@@ -58,3 +60,34 @@ void LLFloaterModelUploadBase::requestAgentUploadPermissions()
mHasUploadPerm = true;
}
}
+
+void LLFloaterModelUploadBase::requestAgentUploadPermissionsCoro(std::string url,
+ LLHandle<LLUploadPermissionsObserver> observerHandle)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("MeshUploadFlag", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+
+ LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ LLUploadPermissionsObserver* observer = observerHandle.get();
+
+ if (!observer)
+ {
+ LL_WARNS("MeshUploadFlag") << "Unable to get observer after call to '" << url << "' aborting." << LL_ENDL;
+ }
+
+ if (!status)
+ {
+ observer->setPermissonsErrorStatus(status.getStatus(), status.getMessage());
+ return;
+ }
+
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ observer->onPermissionsReceived(result);
+}
diff --git a/indra/newview/llfloatermodeluploadbase.h b/indra/newview/llfloatermodeluploadbase.h
index d9a8879687..0d4c834122 100755
--- a/indra/newview/llfloatermodeluploadbase.h
+++ b/indra/newview/llfloatermodeluploadbase.h
@@ -28,6 +28,8 @@
#define LL_LLFLOATERMODELUPLOADBASE_H
#include "lluploadfloaterobservers.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
class LLFloaterModelUploadBase : public LLFloater, public LLUploadPermissionsObserver, public LLWholeModelFeeObserver, public LLWholeModelUploadObserver
{
@@ -54,6 +56,8 @@ protected:
// requests agent's permissions to upload model
void requestAgentUploadPermissions();
+ void requestAgentUploadPermissionsCoro(std::string url, LLHandle<LLUploadPermissionsObserver> observerHandle);
+
std::string mUploadModelUrl;
bool mHasUploadPerm;
};
diff --git a/indra/newview/llfloaternamedesc.cpp b/indra/newview/llfloaternamedesc.cpp
index 0cca715fe2..46dbf85dfa 100755
--- a/indra/newview/llfloaternamedesc.cpp
+++ b/indra/newview/llfloaternamedesc.cpp
@@ -164,14 +164,18 @@ void LLFloaterNameDesc::onBtnOK( )
void *nruserdata = NULL;
std::string display_name = LLStringUtil::null;
- upload_new_resource(mFilenameAndPath, // file
- getChild<LLUICtrl>("name_form")->getValue().asString(),
- getChild<LLUICtrl>("description_form")->getValue().asString(),
- 0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
- LLFloaterPerms::getNextOwnerPerms("Uploads"),
- LLFloaterPerms::getGroupPerms("Uploads"),
- LLFloaterPerms::getEveryonePerms("Uploads"),
- display_name, callback, expected_upload_cost, nruserdata);
+ LLResourceUploadInfo::ptr_t uploadInfo(new NewFileResourceUploadInfo(
+ mFilenameAndPath,
+ getChild<LLUICtrl>("name_form")->getValue().asString(),
+ getChild<LLUICtrl>("description_form")->getValue().asString(), 0,
+ LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
+ LLFloaterPerms::getNextOwnerPerms("Uploads"),
+ LLFloaterPerms::getGroupPerms("Uploads"),
+ LLFloaterPerms::getEveryonePerms("Uploads"),
+ expected_upload_cost));
+
+ upload_new_resource(uploadInfo, callback, nruserdata);
+
closeFloater(false);
}
diff --git a/indra/newview/llfloaterperms.cpp b/indra/newview/llfloaterperms.cpp
index 042cf47070..16bb449fdb 100755
--- a/indra/newview/llfloaterperms.cpp
+++ b/indra/newview/llfloaterperms.cpp
@@ -37,6 +37,7 @@
#include "llnotificationsutil.h"
#include "llsdserialize.h"
#include "llvoavatar.h"
+#include "llcorehttputil.h"
LLFloaterPerms::LLFloaterPerms(const LLSD& seed)
: LLFloater(seed)
@@ -166,41 +167,6 @@ void LLFloaterPermsDefault::onCommitCopy(const LLSD& user_data)
xfer->setEnabled(copyable);
}
-class LLFloaterPermsResponder : public LLHTTPClient::Responder
-{
-public:
- LLFloaterPermsResponder(): LLHTTPClient::Responder() {}
-private:
- static std::string sPreviousReason;
-
- void httpFailure()
- {
- const std::string& reason = getReason();
- // Do not display the same error more than once in a row
- if (reason != sPreviousReason)
- {
- sPreviousReason = reason;
- LLSD args;
- args["REASON"] = reason;
- LLNotificationsUtil::add("DefaultObjectPermissions", args);
- }
- }
-
- void httpSuccess()
- {
- //const LLSD& content = getContent();
- //dump_sequential_xml("perms_responder_result.xml", content);
-
- // Since we have had a successful POST call be sure to display the next error message
- // even if it is the same as a previous one.
- sPreviousReason = "";
- LLFloaterPermsDefault::setCapSent(true);
- LL_INFOS("ObjectPermissionsFloater") << "Default permissions successfully sent to simulator" << LL_ENDL;
- }
-};
-
- std::string LLFloaterPermsResponder::sPreviousReason;
-
void LLFloaterPermsDefault::sendInitialPerms()
{
if(!mCapSent)
@@ -215,23 +181,8 @@ void LLFloaterPermsDefault::updateCap()
if(!object_url.empty())
{
- LLSD report = LLSD::emptyMap();
- report["default_object_perm_masks"]["Group"] =
- (LLSD::Integer)LLFloaterPerms::getGroupPerms(sCategoryNames[CAT_OBJECTS]);
- report["default_object_perm_masks"]["Everyone"] =
- (LLSD::Integer)LLFloaterPerms::getEveryonePerms(sCategoryNames[CAT_OBJECTS]);
- report["default_object_perm_masks"]["NextOwner"] =
- (LLSD::Integer)LLFloaterPerms::getNextOwnerPerms(sCategoryNames[CAT_OBJECTS]);
-
- {
- LL_DEBUGS("ObjectPermissionsFloater") << "Sending default permissions to '"
- << object_url << "'\n";
- std::ostringstream sent_perms_log;
- LLSDSerialize::toPrettyXML(report, sent_perms_log);
- LL_CONT << sent_perms_log.str() << LL_ENDL;
- }
-
- LLHTTPClient::post(object_url, report, new LLFloaterPermsResponder());
+ LLCoros::instance().launch("LLFloaterPermsDefault::updateCapCoro",
+ boost::bind(&LLFloaterPermsDefault::updateCapCoro, object_url));
}
else
{
@@ -239,6 +190,57 @@ void LLFloaterPermsDefault::updateCap()
}
}
+/*static*/
+void LLFloaterPermsDefault::updateCapCoro(std::string url)
+{
+ static std::string previousReason;
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("genericPostCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLSD postData = LLSD::emptyMap();
+ postData["default_object_perm_masks"]["Group"] =
+ (LLSD::Integer)LLFloaterPerms::getGroupPerms(sCategoryNames[CAT_OBJECTS]);
+ postData["default_object_perm_masks"]["Everyone"] =
+ (LLSD::Integer)LLFloaterPerms::getEveryonePerms(sCategoryNames[CAT_OBJECTS]);
+ postData["default_object_perm_masks"]["NextOwner"] =
+ (LLSD::Integer)LLFloaterPerms::getNextOwnerPerms(sCategoryNames[CAT_OBJECTS]);
+
+ {
+ LL_DEBUGS("ObjectPermissionsFloater") << "Sending default permissions to '"
+ << url << "'\n";
+ std::ostringstream sent_perms_log;
+ LLSDSerialize::toPrettyXML(postData, sent_perms_log);
+ LL_CONT << sent_perms_log.str() << LL_ENDL;
+ }
+
+ LLSD result = httpAdapter->postAndYield(httpRequest, url, postData);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ const std::string& reason = status.toString();
+ // Do not display the same error more than once in a row
+ if (reason != previousReason)
+ {
+ previousReason = reason;
+ LLSD args;
+ args["REASON"] = reason;
+ LLNotificationsUtil::add("DefaultObjectPermissions", args);
+ }
+ return;
+ }
+
+ // Since we have had a successful POST call be sure to display the next error message
+ // even if it is the same as a previous one.
+ previousReason.clear();
+ LLFloaterPermsDefault::setCapSent(true);
+ LL_INFOS("ObjectPermissionsFloater") << "Default permissions successfully sent to simulator" << LL_ENDL;
+}
+
void LLFloaterPermsDefault::setCapSent(bool cap_sent)
{
mCapSent = cap_sent;
diff --git a/indra/newview/llfloaterperms.h b/indra/newview/llfloaterperms.h
index 2bb0a19dc1..e866b6de7d 100755
--- a/indra/newview/llfloaterperms.h
+++ b/indra/newview/llfloaterperms.h
@@ -29,6 +29,8 @@
#define LL_LLFLOATERPERMPREFS_H
#include "llfloater.h"
+#include "lleventcoro.h"
+#include "llcoros.h"
class LLFloaterPerms : public LLFloater
{
@@ -80,6 +82,8 @@ private:
void refresh();
static const std::string sCategoryNames[CAT_LAST];
+ static void updateCapCoro(std::string url);
+
// cached values only for implementing cancel.
bool mShareWithGroup[CAT_LAST];
diff --git a/indra/newview/llfloaterregiondebugconsole.cpp b/indra/newview/llfloaterregiondebugconsole.cpp
index 40757a4d04..271fb2f9a3 100755
--- a/indra/newview/llfloaterregiondebugconsole.cpp
+++ b/indra/newview/llfloaterregiondebugconsole.cpp
@@ -30,11 +30,11 @@
#include "llfloaterregiondebugconsole.h"
#include "llagent.h"
-#include "llhttpclient.h"
#include "llhttpnode.h"
#include "lllineeditor.h"
#include "lltexteditor.h"
#include "llviewerregion.h"
+#include "llcorehttputil.h"
// Two versions of the sim console API are supported.
//
@@ -68,58 +68,6 @@ namespace
const std::string CONSOLE_NOT_SUPPORTED(
"This region does not support the simulator console.");
- // This responder handles the initial response. Unless error() is called
- // we assume that the simulator has received our request. Error will be
- // called if this request times out.
- class AsyncConsoleResponder : public LLHTTPClient::Responder
- {
- LOG_CLASS(AsyncConsoleResponder);
- protected:
- /* virtual */
- 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 httpFailure()
- {
- LL_WARNS("Console") << dumpResponse() << LL_ENDL;
- if (mOutput)
- {
- mOutput->appendText(
- UNABLE_TO_SEND_COMMAND + PROMPT,
- false);
- }
- }
-
- /*virtual*/
- void httpSuccess()
- {
- const LLSD& content = getContent();
- LL_DEBUGS("Console") << content << LL_ENDL;
- if (mOutput)
- {
- mOutput->appendText(
- content.asString() + PROMPT, false);
- }
- }
-
- public:
- LLTextEditor * mOutput;
- };
-
// This handles responses for console commands sent via the asynchronous
// API.
class ConsoleResponseNode : public LLHTTPNode
@@ -202,26 +150,57 @@ void LLFloaterRegionDebugConsole::onInput(LLUICtrl* ctrl, const LLSD& param)
}
else
{
- // Using SimConsole (deprecated)
- LLHTTPClient::post(
- url,
- LLSD(input->getText()),
- new ConsoleResponder(mOutput));
+ LLSD postData = LLSD(input->getText());
+ LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(url, postData,
+ boost::bind(&LLFloaterRegionDebugConsole::onConsoleSuccess, this, _1),
+ boost::bind(&LLFloaterRegionDebugConsole::onConsoleError, this, _1));
}
}
else
{
- // Using SimConsoleAsync
- LLHTTPClient::post(
- url,
- LLSD(input->getText()),
- new AsyncConsoleResponder);
+ LLSD postData = LLSD(input->getText());
+ LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(url, postData,
+ NULL,
+ boost::bind(&LLFloaterRegionDebugConsole::onAsyncConsoleError, this, _1));
+
}
mOutput->appendText(text, false);
input->clear();
}
+void LLFloaterRegionDebugConsole::onAsyncConsoleError(LLSD result)
+{
+ LL_WARNS("Console") << UNABLE_TO_SEND_COMMAND << LL_ENDL;
+ sConsoleReplySignal(UNABLE_TO_SEND_COMMAND);
+}
+
+void LLFloaterRegionDebugConsole::onConsoleError(LLSD result)
+{
+ LL_WARNS("Console") << UNABLE_TO_SEND_COMMAND << LL_ENDL;
+ if (mOutput)
+ {
+ mOutput->appendText(
+ UNABLE_TO_SEND_COMMAND + PROMPT,
+ false);
+ }
+
+}
+
+void LLFloaterRegionDebugConsole::onConsoleSuccess(LLSD result)
+{
+ if (mOutput)
+ {
+ LLSD response = result;
+ if (response.isMap() && response.has(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT))
+ {
+ response = response[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT];
+ }
+ mOutput->appendText(
+ response.asString() + PROMPT, false);
+ }
+}
+
void LLFloaterRegionDebugConsole::onReplyReceived(const std::string& output)
{
mOutput->appendText(output + PROMPT, false);
diff --git a/indra/newview/llfloaterregiondebugconsole.h b/indra/newview/llfloaterregiondebugconsole.h
index fd3af4152e..f55d964924 100755
--- a/indra/newview/llfloaterregiondebugconsole.h
+++ b/indra/newview/llfloaterregiondebugconsole.h
@@ -31,14 +31,13 @@
#include <boost/signals2.hpp>
#include "llfloater.h"
-#include "llhttpclient.h"
class LLTextEditor;
typedef boost::signals2::signal<
void (const std::string& output)> console_reply_signal_t;
-class LLFloaterRegionDebugConsole : public LLFloater, public LLHTTPClient::Responder
+class LLFloaterRegionDebugConsole : public LLFloater
{
public:
LLFloaterRegionDebugConsole(LLSD const & key);
@@ -56,6 +55,10 @@ public:
private:
void onReplyReceived(const std::string& output);
+ void onAsyncConsoleError(LLSD result);
+ void onConsoleError(LLSD result);
+ void onConsoleSuccess(LLSD result);
+
boost::signals2::connection mReplySignalConnection;
};
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 5d1e01c1f7..37e934429f 100755
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -97,6 +97,7 @@
#include "llpanelexperiencepicker.h"
#include "llexperiencecache.h"
#include "llpanelexperiences.h"
+#include "llcorehttputil.h"
const S32 TERRAIN_TEXTURE_COUNT = 4;
const S32 CORNER_COUNT = 4;
@@ -803,30 +804,6 @@ bool LLPanelRegionGeneralInfo::onMessageCommit(const LLSD& notification, const L
return false;
}
-class ConsoleRequestResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(ConsoleRequestResponder);
-protected:
- /*virtual*/
- void httpFailure()
- {
- LL_WARNS() << "error requesting mesh_rez_enabled " << dumpResponse() << LL_ENDL;
- }
-};
-
-
-// called if this request times out.
-class ConsoleUpdateResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(ConsoleUpdateResponder);
-protected:
- /* virtual */
- void httpFailure()
- {
- LL_WARNS() << "error updating mesh enabled region setting " << dumpResponse() << LL_ENDL;
- }
-};
-
void LLFloaterRegionInfo::requestMeshRezInfo()
{
std::string sim_console_url = gAgent.getRegion()->getCapability("SimConsoleAsync");
@@ -835,10 +812,8 @@ void LLFloaterRegionInfo::requestMeshRezInfo()
{
std::string request_str = "get mesh_rez_enabled";
- LLHTTPClient::post(
- sim_console_url,
- LLSD(request_str),
- new ConsoleRequestResponder);
+ LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(sim_console_url, LLSD(request_str),
+ "Requested mesh_rez_enabled", "Error requesting mesh_rez_enabled");
}
}
@@ -874,7 +849,8 @@ BOOL LLPanelRegionGeneralInfo::sendUpdate()
body["allow_parcel_changes"] = getChild<LLUICtrl>("allow_parcel_changes_check")->getValue();
body["block_parcel_search"] = getChild<LLUICtrl>("block_parcel_search_check")->getValue();
- LLHTTPClient::post(url, body, new LLHTTPClient::Responder());
+ LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, body,
+ "Region info update posted.", "Region info update not posted.");
}
else
{
@@ -2303,36 +2279,6 @@ 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 httpSuccess()
- {
- LL_INFOS("Windlight") << "Successfully committed estate info" << LL_ENDL;
-
- // refresh the panel from the database
- LLPanelEstateInfo* panel = dynamic_cast<LLPanelEstateInfo*>(mpPanel.get());
- if (panel)
- panel->refresh();
- }
-
- // if we get an error response
- virtual void httpFailure()
- {
- LL_WARNS("Windlight") << dumpResponse() << LL_ENDL;
- }
-private:
- LLHandle<LLPanel> mpPanel;
-};
-
const std::string LLPanelEstateInfo::getOwnerName() const
{
return getChild<LLUICtrl>("estate_owner")->getValue().asString();
diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h
index e7b49d8553..90f115faaf 100755
--- a/indra/newview/llfloaterregioninfo.h
+++ b/indra/newview/llfloaterregioninfo.h
@@ -36,6 +36,7 @@
#include "llextendedstatus.h"
#include "llenvmanager.h" // for LLEnvironmentSettings
+#include "lleventcoro.h"
class LLAvatarName;
class LLDispatcher;
@@ -107,6 +108,8 @@ private:
LLFloaterRegionInfo(const LLSD& seed);
~LLFloaterRegionInfo();
+
+
protected:
void onTabSelected(const LLSD& param);
diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp
index 5fbdd75e97..14719a77f9 100755
--- a/indra/newview/llfloaterscriptlimits.cpp
+++ b/indra/newview/llfloaterscriptlimits.cpp
@@ -50,6 +50,7 @@
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
#include "llviewerwindow.h"
+#include "llcorehttputil.h"
///----------------------------------------------------------------------------
/// LLFloaterScriptLimits
@@ -180,372 +181,6 @@ void LLPanelScriptLimitsInfo::updateChild(LLUICtrl* child_ctr)
}
///----------------------------------------------------------------------------
-// Responders
-///----------------------------------------------------------------------------
-
-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
-
- LLSDNotationStreamer notation_streamer(content);
- std::ostringstream nice_llsd;
- nice_llsd << notation_streamer;
-
- OSMessageBox(nice_llsd.str(), "main cap response:", 0);
-
- LL_INFOS() << "main cap response:" << content << LL_ENDL;
-
-#endif
-
- // at this point we have an llsd which should contain ether one or two urls to the services we want.
- // first we look for the details service:
- if(content.has("ScriptResourceDetails"))
- {
- LLHTTPClient::get(content["ScriptResourceDetails"], new fetchScriptLimitsRegionDetailsResponder(mInfo));
- }
- else
- {
- LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
- if(!instance)
- {
- LL_WARNS() << "Failed to get llfloaterscriptlimits instance" << LL_ENDL;
- }
- }
-
- // then the summary service:
- if(content.has("ScriptResourceSummary"))
- {
- LLHTTPClient::get(content["ScriptResourceSummary"], new fetchScriptLimitsRegionSummaryResponder(mInfo));
- }
-}
-
-void fetchScriptLimitsRegionInfoResponder::httpFailure()
-{
- LL_WARNS() << dumpResponse() << LL_ENDL;
-}
-
-void fetchScriptLimitsRegionSummaryResponder::httpSuccess()
-{
- const LLSD& content_ref = getContent();
-#ifdef USE_FAKE_RESPONSES
-
- LLSD fake_content;
- LLSD summary = LLSD::emptyMap();
- LLSD available = LLSD::emptyArray();
- LLSD available_urls = LLSD::emptyMap();
- LLSD available_memory = LLSD::emptyMap();
- LLSD used = LLSD::emptyArray();
- LLSD used_urls = LLSD::emptyMap();
- LLSD used_memory = LLSD::emptyMap();
-
- used_urls["type"] = "urls";
- used_urls["amount"] = FAKE_NUMBER_OF_URLS;
- available_urls["type"] = "urls";
- available_urls["amount"] = FAKE_AVAILABLE_URLS;
- used_memory["type"] = "memory";
- used_memory["amount"] = FAKE_AMOUNT_OF_MEMORY;
- available_memory["type"] = "memory";
- available_memory["amount"] = FAKE_AVAILABLE_MEMORY;
-
-//summary response:{'summary':{'available':[{'amount':i731,'type':'urls'},{'amount':i895577,'type':'memory'},{'amount':i731,'type':'urls'},{'amount':i895577,'type':'memory'}],'used':[{'amount':i329,'type':'urls'},{'amount':i66741,'type':'memory'}]}}
-
- used.append(used_urls);
- used.append(used_memory);
- available.append(available_urls);
- available.append(available_memory);
-
- summary["available"] = available;
- summary["used"] = used;
-
- fake_content["summary"] = summary;
-
- const LLSD& content = fake_content;
-
-#else
-
- const LLSD& content = content_ref;
-
-#endif
-
- if (!content.isMap())
- {
- failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
- return;
- }
-
-
-#ifdef DUMP_REPLIES_TO_LLINFOS
-
- LLSDNotationStreamer notation_streamer(content);
- std::ostringstream nice_llsd;
- nice_llsd << notation_streamer;
-
- OSMessageBox(nice_llsd.str(), "summary response:", 0);
-
- LL_WARNS() << "summary response:" << *content << LL_ENDL;
-
-#endif
-
- LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
- if(!instance)
- {
- LL_WARNS() << "Failed to get llfloaterscriptlimits instance" << LL_ENDL;
- }
- else
- {
- LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");
- if(tab)
- {
- 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("")));
-
- LLButton* btn = panel_memory->getChild<LLButton>("refresh_list_btn");
- if(btn)
- {
- btn->setEnabled(true);
- }
-
- panel_memory->setRegionSummary(content);
- }
- }
- }
-}
-
-void fetchScriptLimitsRegionSummaryResponder::httpFailure()
-{
- LL_WARNS() << dumpResponse() << LL_ENDL;
-}
-
-void fetchScriptLimitsRegionDetailsResponder::httpSuccess()
-{
- const LLSD& content_ref = getContent();
-#ifdef USE_FAKE_RESPONSES
-/*
-Updated detail service, ** denotes field added:
-
-result (map)
-+-parcels (array of maps)
- +-id (uuid)
- +-local_id (S32)**
- +-name (string)
- +-owner_id (uuid) (in ERS as owner, but owner_id in code)
- +-objects (array of maps)
- +-id (uuid)
- +-name (string)
- +-owner_id (uuid) (in ERS as owner, in code as owner_id)
- +-owner_name (sting)**
- +-location (map)**
- +-x (float)
- +-y (float)
- +-z (float)
- +-resources (map) (this is wrong in the ERS but right in code)
- +-type (string)
- +-amount (int)
-*/
- LLSD fake_content;
- LLSD resource = LLSD::emptyMap();
- LLSD location = LLSD::emptyMap();
- LLSD object = LLSD::emptyMap();
- LLSD objects = LLSD::emptyArray();
- LLSD parcel = LLSD::emptyMap();
- LLSD parcels = LLSD::emptyArray();
-
- resource["urls"] = FAKE_NUMBER_OF_URLS;
- resource["memory"] = FAKE_AMOUNT_OF_MEMORY;
-
- location["x"] = 128.0f;
- location["y"] = 128.0f;
- location["z"] = 0.0f;
-
- object["id"] = LLUUID("d574a375-0c6c-fe3d-5733-da669465afc7");
- object["name"] = "Gabs fake Object!";
- object["owner_id"] = LLUUID("8dbf2d41-69a0-4e5e-9787-0c9d297bc570");
- object["owner_name"] = "Gabs Linden";
- object["location"] = location;
- object["resources"] = resource;
-
- objects.append(object);
-
- parcel["id"] = LLUUID("da05fb28-0d20-e593-2728-bddb42dd0160");
- parcel["local_id"] = 42;
- parcel["name"] = "Gabriel Linden\'s Sub Plot";
- parcel["objects"] = objects;
- parcels.append(parcel);
-
- fake_content["parcels"] = parcels;
- const LLSD& content = fake_content;
-
-#else
-
- const LLSD& content = content_ref;
-
-#endif
-
- if (!content.isMap())
- {
- failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
- return;
- }
-
-#ifdef DUMP_REPLIES_TO_LLINFOS
-
- LLSDNotationStreamer notation_streamer(content);
- std::ostringstream nice_llsd;
- nice_llsd << notation_streamer;
-
- OSMessageBox(nice_llsd.str(), "details response:", 0);
-
- LL_INFOS() << "details response:" << content << LL_ENDL;
-
-#endif
-
- LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
-
- if(!instance)
- {
- LL_WARNS() << "Failed to get llfloaterscriptlimits instance" << LL_ENDL;
- }
- else
- {
- LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");
- if(tab)
- {
- LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel");
- if(panel_memory)
- {
- panel_memory->setRegionDetails(content);
- }
- else
- {
- LL_WARNS() << "Failed to get scriptlimits memory panel" << LL_ENDL;
- }
- }
- else
- {
- LL_WARNS() << "Failed to get scriptlimits_panels" << LL_ENDL;
- }
- }
-}
-
-void fetchScriptLimitsRegionDetailsResponder::httpFailure()
-{
- LL_WARNS() << dumpResponse() << LL_ENDL;
-}
-
-void fetchScriptLimitsAttachmentInfoResponder::httpSuccess()
-{
- const LLSD& content_ref = getContent();
-
-#ifdef USE_FAKE_RESPONSES
-
- // just add the summary, as that's all I'm testing currently!
- LLSD fake_content = LLSD::emptyMap();
- LLSD summary = LLSD::emptyMap();
- LLSD available = LLSD::emptyArray();
- LLSD available_urls = LLSD::emptyMap();
- LLSD available_memory = LLSD::emptyMap();
- LLSD used = LLSD::emptyArray();
- LLSD used_urls = LLSD::emptyMap();
- LLSD used_memory = LLSD::emptyMap();
-
- used_urls["type"] = "urls";
- used_urls["amount"] = FAKE_NUMBER_OF_URLS;
- available_urls["type"] = "urls";
- available_urls["amount"] = FAKE_AVAILABLE_URLS;
- used_memory["type"] = "memory";
- used_memory["amount"] = FAKE_AMOUNT_OF_MEMORY;
- available_memory["type"] = "memory";
- available_memory["amount"] = FAKE_AVAILABLE_MEMORY;
-
- used.append(used_urls);
- used.append(used_memory);
- available.append(available_urls);
- available.append(available_memory);
-
- summary["available"] = available;
- summary["used"] = used;
-
- fake_content["summary"] = summary;
- fake_content["attachments"] = content_ref["attachments"];
-
- const LLSD& content = fake_content;
-
-#else
-
- const LLSD& content = content_ref;
-
-#endif
-
- if (!content.isMap())
- {
- failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
- return;
- }
-
-#ifdef DUMP_REPLIES_TO_LLINFOS
-
- LLSDNotationStreamer notation_streamer(content);
- std::ostringstream nice_llsd;
- nice_llsd << notation_streamer;
-
- OSMessageBox(nice_llsd.str(), "attachment response:", 0);
-
- LL_INFOS() << "attachment response:" << content << LL_ENDL;
-
-#endif
-
- LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
-
- if(!instance)
- {
- LL_WARNS() << "Failed to get llfloaterscriptlimits instance" << LL_ENDL;
- }
- else
- {
- LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");
- if(tab)
- {
- LLPanelScriptLimitsAttachment* panel = (LLPanelScriptLimitsAttachment*)tab->getChild<LLPanel>("script_limits_my_avatar_panel");
- if(panel)
- {
- panel->getChild<LLUICtrl>("loading_text")->setValue(LLSD(std::string("")));
-
- LLButton* btn = panel->getChild<LLButton>("refresh_list_btn");
- if(btn)
- {
- btn->setEnabled(true);
- }
-
- panel->setAttachmentDetails(content);
- }
- else
- {
- LL_WARNS() << "Failed to get script_limits_my_avatar_panel" << LL_ENDL;
- }
- }
- else
- {
- LL_WARNS() << "Failed to get scriptlimits_panels" << LL_ENDL;
- }
- }
-}
-
-void fetchScriptLimitsAttachmentInfoResponder::httpFailure()
-{
- LL_WARNS() << dumpResponse() << LL_ENDL;
-}
-
-///----------------------------------------------------------------------------
// Memory Panel
///----------------------------------------------------------------------------
@@ -564,12 +199,8 @@ BOOL LLPanelScriptLimitsRegionMemory::getLandScriptResources()
std::string url = gAgent.getRegion()->getCapability("LandResources");
if (!url.empty())
{
- body["parcel_id"] = mParcelId;
-
- LLSD info;
- info["parcel_id"] = mParcelId;
- LLHTTPClient::post(url, body, new fetchScriptLimitsRegionInfoResponder(info));
-
+ LLCoros::instance().launch("LLPanelScriptLimitsRegionMemory::getLandScriptResourcesCoro",
+ boost::bind(&LLPanelScriptLimitsRegionMemory::getLandScriptResourcesCoro, this, url));
return TRUE;
}
else
@@ -578,6 +209,147 @@ BOOL LLPanelScriptLimitsRegionMemory::getLandScriptResources()
}
}
+void LLPanelScriptLimitsRegionMemory::getLandScriptResourcesCoro(std::string url)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getLandScriptResourcesCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLSD postData;
+
+ postData["parcel_id"] = mParcelId;
+
+ LLSD result = httpAdapter->postAndYield(httpRequest, url, postData);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS() << "Failed to get script resource info" << LL_ENDL;
+ return;
+ }
+
+ // We could retrieve these sequentially inline from this coroutine. But
+ // since the original code retrieved them in parallel I'll spawn two
+ // coroutines to do the retrieval.
+
+ // The summary service:
+ if (result.has("ScriptResourceSummary"))
+ {
+ std::string urlResourceSummary = result["ScriptResourceSummary"].asString();
+ LLCoros::instance().launch("LLPanelScriptLimitsRegionMemory::getLandScriptSummaryCoro",
+ boost::bind(&LLPanelScriptLimitsRegionMemory::getLandScriptSummaryCoro, this, urlResourceSummary));
+ }
+
+ if (result.has("ScriptResourceDetails"))
+ {
+ std::string urlResourceDetails = result["ScriptResourceDetails"].asString();
+ LLCoros::instance().launch("LLPanelScriptLimitsRegionMemory::getLandScriptDetailsCoro",
+ boost::bind(&LLPanelScriptLimitsRegionMemory::getLandScriptDetailsCoro, this, urlResourceDetails));
+ }
+
+
+}
+
+void LLPanelScriptLimitsRegionMemory::getLandScriptSummaryCoro(std::string url)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getLandScriptSummaryCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS() << "Unable to retrieve script summary." << LL_ENDL;
+ return;
+ }
+
+ LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
+ if (!instance)
+ {
+ LL_WARNS() << "Failed to get llfloaterscriptlimits instance" << LL_ENDL;
+ return;
+ }
+
+ LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");
+ if (!tab)
+ {
+ LL_WARNS() << "Unable to access script limits tab" << LL_ENDL;
+ return;
+ }
+
+ LLPanelScriptLimitsRegionMemory* panelMemory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel");
+ if (!panelMemory)
+ {
+ LL_WARNS() << "Unable to get memory panel." << LL_ENDL;
+ return;
+ }
+
+ panelMemory->getChild<LLUICtrl>("loading_text")->setValue(LLSD(std::string("")));
+
+ LLButton* btn = panelMemory->getChild<LLButton>("refresh_list_btn");
+ if (btn)
+ {
+ btn->setEnabled(true);
+ }
+
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ panelMemory->setRegionSummary(result);
+
+}
+
+void LLPanelScriptLimitsRegionMemory::getLandScriptDetailsCoro(std::string url)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getLandScriptDetailsCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS() << "Unable to retrieve script details." << LL_ENDL;
+ return;
+ }
+
+ LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
+
+ if (!instance)
+ {
+ LL_WARNS() << "Failed to get llfloaterscriptlimits instance" << LL_ENDL;
+ return;
+ }
+
+ LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");
+ if (!tab)
+ {
+ LL_WARNS() << "Unable to access script limits tab" << LL_ENDL;
+ return;
+ }
+
+ LLPanelScriptLimitsRegionMemory* panelMemory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel");
+
+ if (!panelMemory)
+ {
+ LL_WARNS() << "Unable to get memory panel." << LL_ENDL;
+ return;
+ }
+
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ panelMemory->setRegionDetails(result);
+}
+
void LLPanelScriptLimitsRegionMemory::processParcelInfo(const LLParcelData& parcel_data)
{
if(!getLandScriptResources())
@@ -935,17 +707,8 @@ BOOL LLPanelScriptLimitsRegionMemory::StartRequestChain()
std::string url = region->getCapability("RemoteParcelRequest");
if (!url.empty())
{
- body["location"] = ll_sd_from_vector3(parcel_center);
- if (!region_id.isNull())
- {
- body["region_id"] = region_id;
- }
- if (!pos_global.isExactlyZero())
- {
- U64 region_handle = to_region_handle(pos_global);
- body["region_handle"] = ll_sd_from_U64(region_handle);
- }
- LLHTTPClient::post(url, body, new LLRemoteParcelRequestResponder(getObserverHandle()));
+ LLRemoteParcelInfoProcessor::getInstance()->requestRegionParcelInfo(url,
+ region_id, parcel_center, pos_global, getObserverHandle());
}
else
{
@@ -1183,7 +946,8 @@ BOOL LLPanelScriptLimitsAttachment::requestAttachmentDetails()
std::string url = gAgent.getRegion()->getCapability("AttachmentResources");
if (!url.empty())
{
- LLHTTPClient::get(url, body, new fetchScriptLimitsAttachmentInfoResponder());
+ LLCoros::instance().launch("LLPanelScriptLimitsAttachment::getAttachmentLimitsCoro",
+ boost::bind(&LLPanelScriptLimitsAttachment::getAttachmentLimitsCoro, this, url));
return TRUE;
}
else
@@ -1192,6 +956,59 @@ BOOL LLPanelScriptLimitsAttachment::requestAttachmentDetails()
}
}
+void LLPanelScriptLimitsAttachment::getAttachmentLimitsCoro(std::string url)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getAttachmentLimitsCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS() << "Unable to retrieve attachment limits." << LL_ENDL;
+ return;
+ }
+
+ LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits");
+
+ if (!instance)
+ {
+ LL_WARNS() << "Failed to get llfloaterscriptlimits instance" << LL_ENDL;
+ return;
+ }
+
+ LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels");
+ if (!tab)
+ {
+ LL_WARNS() << "Failed to get scriptlimits_panels" << LL_ENDL;
+ return;
+ }
+
+ LLPanelScriptLimitsAttachment* panel = (LLPanelScriptLimitsAttachment*)tab->getChild<LLPanel>("script_limits_my_avatar_panel");
+ if (!panel)
+ {
+ LL_WARNS() << "Failed to get script_limits_my_avatar_panel" << LL_ENDL;
+ return;
+ }
+
+ panel->getChild<LLUICtrl>("loading_text")->setValue(LLSD(std::string("")));
+
+ LLButton* btn = panel->getChild<LLButton>("refresh_list_btn");
+ if (btn)
+ {
+ btn->setEnabled(true);
+ }
+
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ panel->setAttachmentDetails(result);
+}
+
+
void LLPanelScriptLimitsAttachment::setAttachmentDetails(LLSD content)
{
LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list");
diff --git a/indra/newview/llfloaterscriptlimits.h b/indra/newview/llfloaterscriptlimits.h
index 5ba0185d32..e3cbbd185f 100755
--- a/indra/newview/llfloaterscriptlimits.h
+++ b/indra/newview/llfloaterscriptlimits.h
@@ -33,6 +33,8 @@
#include "llhost.h"
#include "llpanel.h"
#include "llremoteparcelrequest.h"
+#include "lleventcoro.h"
+#include "llcoros.h"
class LLPanelScriptLimitsInfo;
class LLTabContainer;
@@ -80,57 +82,6 @@ protected:
};
/////////////////////////////////////////////////////////////////////////////
-// Responders
-/////////////////////////////////////////////////////////////////////////////
-
-class fetchScriptLimitsRegionInfoResponder: public LLHTTPClient::Responder
-{
- LOG_CLASS(fetchScriptLimitsRegionInfoResponder);
-public:
- fetchScriptLimitsRegionInfoResponder(const LLSD& info) : mInfo(info) {};
-
-private:
- /* virtual */ void httpSuccess();
- /* virtual */ void httpFailure();
- LLSD mInfo;
-};
-
-class fetchScriptLimitsRegionSummaryResponder: public LLHTTPClient::Responder
-{
- LOG_CLASS(fetchScriptLimitsRegionSummaryResponder);
-public:
- fetchScriptLimitsRegionSummaryResponder(const LLSD& info) : mInfo(info) {};
-
-private:
- /* virtual */ void httpSuccess();
- /* virtual */ void httpFailure();
- LLSD mInfo;
-};
-
-class fetchScriptLimitsRegionDetailsResponder: public LLHTTPClient::Responder
-{
- LOG_CLASS(fetchScriptLimitsRegionDetailsResponder);
-public:
- fetchScriptLimitsRegionDetailsResponder(const LLSD& info) : mInfo(info) {};
-
-private:
- /* virtual */ void httpSuccess();
- /* virtual */ void httpFailure();
- LLSD mInfo;
-};
-
-class fetchScriptLimitsAttachmentInfoResponder: public LLHTTPClient::Responder
-{
- LOG_CLASS(fetchScriptLimitsAttachmentInfoResponder);
-public:
- fetchScriptLimitsAttachmentInfoResponder() {};
-
-private:
- /* virtual */ void httpSuccess();
- /* virtual */ void httpFailure();
-};
-
-/////////////////////////////////////////////////////////////////////////////
// Memory panel
/////////////////////////////////////////////////////////////////////////////
@@ -181,6 +132,10 @@ private:
std::vector<LLSD> mObjectListItems;
+ void getLandScriptResourcesCoro(std::string url);
+ void getLandScriptSummaryCoro(std::string url);
+ void getLandScriptDetailsCoro(std::string url);
+
protected:
// LLRemoteParcelInfoObserver interface:
@@ -225,6 +180,7 @@ public:
void clearList();
private:
+ void getAttachmentLimitsCoro(std::string url);
bool mGotAttachmentMemoryUsed;
S32 mAttachmentMemoryMax;
diff --git a/indra/newview/llfloatertos.cpp b/indra/newview/llfloatertos.cpp
index c1c21c593e..6dc08417d7 100755
--- a/indra/newview/llfloatertos.cpp
+++ b/indra/newview/llfloatertos.cpp
@@ -35,8 +35,6 @@
// linden library includes
#include "llbutton.h"
#include "llevents.h"
-#include "llhttpclient.h"
-#include "llhttpconstants.h"
#include "llnotificationsutil.h"
#include "llradiogroup.h"
#include "lltextbox.h"
@@ -45,7 +43,7 @@
#include "llvfile.h"
#include "message.h"
#include "llstartup.h" // login_alert_done
-
+#include "llcorehttputil.h"
LLFloaterTOS::LLFloaterTOS(const LLSD& data)
: LLModalDialog( data["message"].asString() ),
@@ -57,57 +55,6 @@ LLFloaterTOS::LLFloaterTOS(const LLSD& data)
{
}
-// helper class that trys to download a URL from a web site and calls a method
-// on parent class indicating if the web server is working or not
-class LLIamHere : public LLHTTPClient::Responder
-{
- LOG_CLASS(LLIamHere);
-private:
- LLIamHere( LLFloaterTOS* parent ) :
- mParent( parent )
- {}
-
- LLFloaterTOS* mParent;
-
-public:
- static LLIamHere* build( LLFloaterTOS* parent )
- {
- return new LLIamHere( parent );
- }
-
- virtual void setParent( LLFloaterTOS* parentIn )
- {
- mParent = parentIn;
- }
-
-protected:
- virtual void httpSuccess()
- {
- if ( mParent )
- {
- mParent->setSiteIsAlive( true );
- }
- }
-
- virtual void httpFailure()
- {
- LL_DEBUGS("LLIamHere") << dumpResponse() << LL_ENDL;
- 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 = (getStatus() == HTTP_FOUND);
- mParent->setSiteIsAlive( alive );
- }
- }
-};
-
-// this is global and not a class member to keep crud out of the header file
-namespace {
- LLPointer< LLIamHere > gResponsePtr = 0;
-};
-
BOOL LLFloaterTOS::postBuild()
{
childSetAction("Continue", onContinue, this);
@@ -180,9 +127,6 @@ void LLFloaterTOS::setSiteIsAlive( bool alive )
LLFloaterTOS::~LLFloaterTOS()
{
- // tell the responder we're not here anymore
- if ( gResponsePtr )
- gResponsePtr->setParent( 0 );
}
// virtual
@@ -243,9 +187,10 @@ void LLFloaterTOS::handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent ev
if(!mLoadingScreenLoaded)
{
mLoadingScreenLoaded = true;
+ std::string url(getString("real_url"));
- gResponsePtr = LLIamHere::build( this );
- LLHTTPClient::get( getString( "real_url" ), gResponsePtr );
+ LLCoros::instance().launch("LLFloaterTOS::testSiteIsAliveCoro",
+ boost::bind(&LLFloaterTOS::testSiteIsAliveCoro, this, url));
}
else if(mRealNavigateBegun)
{
@@ -257,3 +202,26 @@ void LLFloaterTOS::handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent ev
}
}
+void LLFloaterTOS::testSiteIsAliveCoro(std::string url)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("genericPostCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
+
+ httpOpts->setWantHeaders(true);
+
+ LL_INFOS("HttpCoroutineAdapter", "genericPostCoro") << "Generic POST for " << url << LL_ENDL;
+
+ LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ // double not.
+ // First ! returns a boolean error status, second ! is true if success result.
+ setSiteIsAlive(!!status);
+}
+
+
diff --git a/indra/newview/llfloatertos.h b/indra/newview/llfloatertos.h
index 47126d06a6..2748b20513 100755
--- a/indra/newview/llfloatertos.h
+++ b/indra/newview/llfloatertos.h
@@ -31,6 +31,8 @@
#include "llassetstorage.h"
#include "llmediactrl.h"
#include <boost/function.hpp>
+#include "lleventcoro.h"
+#include "llcoros.h"
class LLButton;
class LLRadioGroup;
@@ -60,12 +62,15 @@ public:
/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
private:
+ void testSiteIsAliveCoro(std::string url);
std::string mMessage;
bool mLoadingScreenLoaded;
bool mSiteAlive;
bool mRealNavigateBegun;
std::string mReplyPumpName;
+
+
};
#endif // LL_LLFLOATERTOS_H
diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp
index e02e8eeb5a..6683a6e6e6 100755
--- a/indra/newview/llfloaterurlentry.cpp
+++ b/indra/newview/llfloaterurlentry.cpp
@@ -26,8 +26,6 @@
#include "llviewerprecompiledheaders.h"
-#include "llhttpclient.h"
-
#include "llfloaterurlentry.h"
#include "llpanellandmedia.h"
@@ -40,40 +38,10 @@
#include "lluictrlfactory.h"
#include "llwindow.h"
#include "llviewerwindow.h"
+#include "llcorehttputil.h"
static LLFloaterURLEntry* sInstance = NULL;
-// Move this to its own file.
-// helper class that tries to download a URL from a web site and calls a method
-// 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;
-
-private:
- /* virtual */ void httpCompleted()
- {
- const std::string& media_type = getResponseHeader(HTTP_IN_HEADER_CONTENT_TYPE);
- 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 );
- }
- }
-};
-
//-----------------------------------------------------------------------------
// LLFloaterURLEntry()
//-----------------------------------------------------------------------------
@@ -225,8 +193,8 @@ void LLFloaterURLEntry::onBtnOK( void* userdata )
if(!media_url.empty() &&
(scheme == "http" || scheme == "https"))
{
- LLHTTPClient::getHeaderOnly( media_url,
- new LLMediaTypeResponder(self->getHandle()));
+ LLCoros::instance().launch("LLFloaterURLEntry::getMediaTypeCoro",
+ boost::bind(&LLFloaterURLEntry::getMediaTypeCoro, media_url, self->getHandle()));
}
else
{
@@ -240,6 +208,58 @@ void LLFloaterURLEntry::onBtnOK( void* userdata )
}
// static
+void LLFloaterURLEntry::getMediaTypeCoro(std::string url, LLHandle<LLFloater> parentHandle)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getMediaTypeCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
+
+ httpOpts->setHeadersOnly(true);
+
+ LL_INFOS("HttpCoroutineAdapter", "genericPostCoro") << "Generic POST for " << url << LL_ENDL;
+
+ LLSD result = httpAdapter->getAndYield(httpRequest, url, httpOpts);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ LLFloaterURLEntry* floaterUrlEntry = (LLFloaterURLEntry*)parentHandle.get();
+ if (!floaterUrlEntry)
+ {
+ LL_WARNS() << "Could not get URL entry floater." << LL_ENDL;
+ return;
+ }
+
+ // Set empty type to none/none. Empty string is reserved for legacy parcels
+ // which have no mime type set.
+ std::string resolvedMimeType = LLMIMETypes::getDefaultMimeType();
+
+ if (!status)
+ {
+ floaterUrlEntry->headerFetchComplete(status.getType(), resolvedMimeType);
+ return;
+ }
+
+ LLSD resultHeaders = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
+
+ if (resultHeaders.has(HTTP_IN_HEADER_CONTENT_TYPE))
+ {
+ const std::string& mediaType = resultHeaders[HTTP_IN_HEADER_CONTENT_TYPE];
+ std::string::size_type idx1 = mediaType.find_first_of(";");
+ std::string mimeType = mediaType.substr(0, idx1);
+ if (!mimeType.empty())
+ {
+ resolvedMimeType = mimeType;
+ }
+ }
+
+ floaterUrlEntry->headerFetchComplete(status.getType(), resolvedMimeType);
+
+}
+
+// static
//-----------------------------------------------------------------------------
// onBtnCancel()
//-----------------------------------------------------------------------------
diff --git a/indra/newview/llfloaterurlentry.h b/indra/newview/llfloaterurlentry.h
index bdd1ebe592..20f4604907 100755
--- a/indra/newview/llfloaterurlentry.h
+++ b/indra/newview/llfloaterurlentry.h
@@ -29,6 +29,8 @@
#include "llfloater.h"
#include "llpanellandmedia.h"
+#include "lleventcoro.h"
+#include "llcoros.h"
class LLLineEditor;
class LLComboBox;
@@ -56,7 +58,10 @@ private:
static void onBtnOK(void*);
static void onBtnCancel(void*);
static void onBtnClear(void*);
- bool callback_clear_url_list(const LLSD& notification, const LLSD& response);
+ bool callback_clear_url_list(const LLSD& notification, const LLSD& response);
+
+ static void getMediaTypeCoro(std::string url, LLHandle<LLFloater> parentHandle);
+
};
#endif // LL_LLFLOATERURLENTRY_H
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 56e671d902..edae0bfd19 100755
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -53,6 +53,7 @@
#include "lltrans.h"
#include "llviewerregion.h"
#include <boost/regex.hpp>
+#include "llcorehttputil.h"
#if LL_MSVC
#pragma warning(push)
@@ -768,9 +769,9 @@ void LLGroupMgrGroupData::removeBanEntry(const LLUUID& ban_id)
// LLGroupMgr
//
-LLGroupMgr::LLGroupMgr()
+LLGroupMgr::LLGroupMgr():
+ mMemberRequestInFlight(false)
{
- mLastGroupMembersRequestFrame = 0;
}
LLGroupMgr::~LLGroupMgr()
@@ -1861,49 +1862,94 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id,
group_datap->mMemberVersion.generate();
}
-
-// Responder class for capability group management
-class GroupBanDataResponder : public LLHTTPClient::Responder
+void LLGroupMgr::getGroupBanRequestCoro(std::string url, LLUUID groupId)
{
-public:
- GroupBanDataResponder(const LLUUID& gropup_id, BOOL force_refresh=false);
- virtual ~GroupBanDataResponder() {}
- virtual void httpSuccess();
- virtual void httpFailure();
-private:
- LLUUID mGroupID;
- BOOL mForceRefresh;
-};
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("groupMembersRequest", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
-GroupBanDataResponder::GroupBanDataResponder(const LLUUID& gropup_id, BOOL force_refresh) :
- mGroupID(gropup_id),
- mForceRefresh(force_refresh)
-{}
+ std::string finalUrl = url + "?group_id=" + groupId.asString();
-void GroupBanDataResponder::httpFailure()
-{
- LL_WARNS("GrpMgr") << "Error receiving group member data [status:"
- << mStatus << "]: " << mContent << LL_ENDL;
+ LLSD result = httpAdapter->getAndYield(httpRequest, finalUrl);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS("GrpMgr") << "Error receiving group member data " << LL_ENDL;
+ return;
+ }
+
+ if (result.has("ban_list"))
+ {
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ // group ban data received
+ processGroupBanRequest(result);
+ }
}
-void GroupBanDataResponder::httpSuccess()
+void LLGroupMgr::postGroupBanRequestCoro(std::string url, LLUUID groupId,
+ U32 action, uuid_vec_t banList, bool update)
{
- if (mContent.has("ban_list"))
- {
- // group ban data received
- LLGroupMgr::processGroupBanRequest(mContent);
- }
- else if (mForceRefresh)
- {
- // no ban data received, refreshing data after successful operation
- LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_GET, mGroupID);
- }
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("groupMembersRequest", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
+ LLCore::HttpOptions::ptr_t httpOptions(new LLCore::HttpOptions);
+
+ httpOptions->setFollowRedirects(false);
+
+ httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML);
+
+
+ std::string finalUrl = url + "?group_id=" + groupId.asString();
+
+ LLSD postData = LLSD::emptyMap();
+ postData["ban_action"] = (LLSD::Integer)action;
+ // Add our list of potential banned residents to the list
+ postData["ban_ids"] = LLSD::emptyArray();
+ LLSD banEntry;
+
+ uuid_vec_t::const_iterator it = banList.begin();
+ for (; it != banList.end(); ++it)
+ {
+ banEntry = (*it);
+ postData["ban_ids"].append(banEntry);
+ }
+
+ LL_WARNS() << "post: " << ll_pretty_print_sd(postData) << LL_ENDL;
+
+ LLSD result = httpAdapter->postAndYield(httpRequest, finalUrl, postData, httpOptions, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS("GrpMgr") << "Error posting group member data " << LL_ENDL;
+ return;
+ }
+
+ if (result.has("ban_list"))
+ {
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ // group ban data received
+ processGroupBanRequest(result);
+ }
+
+ if (update)
+ {
+ getGroupBanRequestCoro(url, groupId);
+ }
}
void LLGroupMgr::sendGroupBanRequest( EBanRequestType request_type,
const LLUUID& group_id,
U32 ban_action, /* = BAN_NO_ACTION */
- const std::vector<LLUUID> ban_list) /* = std::vector<LLUUID>() */
+ const std::vector<LLUUID> &ban_list) /* = std::vector<LLUUID>() */
{
LLViewerRegion* currentRegion = gAgent.getRegion();
if(!currentRegion)
@@ -1925,37 +1971,27 @@ void LLGroupMgr::sendGroupBanRequest( EBanRequestType request_type,
{
return;
}
- cap_url += "?group_id=" + group_id.asString();
-
- LLSD body = LLSD::emptyMap();
- body["ban_action"] = (LLSD::Integer)(ban_action & ~BAN_UPDATE);
- // Add our list of potential banned residents to the list
- body["ban_ids"] = LLSD::emptyArray();
- LLSD ban_entry;
- uuid_vec_t::const_iterator iter = ban_list.begin();
- for(;iter != ban_list.end(); ++iter)
- {
- ban_entry = (*iter);
- body["ban_ids"].append(ban_entry);
- }
+ U32 action = ban_action & ~BAN_UPDATE;
+ bool update = ((ban_action & BAN_UPDATE) == BAN_UPDATE);
- LLHTTPClient::ResponderPtr grp_ban_responder = new GroupBanDataResponder(group_id, ban_action & BAN_UPDATE);
- switch(request_type)
- {
- case REQUEST_GET:
- LLHTTPClient::get(cap_url, grp_ban_responder);
- break;
- case REQUEST_POST:
- LLHTTPClient::post(cap_url, body, grp_ban_responder);
- break;
- case REQUEST_PUT:
- case REQUEST_DEL:
- break;
- }
+ switch (request_type)
+ {
+ case REQUEST_GET:
+ LLCoros::instance().launch("LLGroupMgr::getGroupBanRequestCoro",
+ boost::bind(&LLGroupMgr::getGroupBanRequestCoro, this, cap_url, group_id));
+ break;
+ case REQUEST_POST:
+ LLCoros::instance().launch("LLGroupMgr::postGroupBanRequestCoro",
+ boost::bind(&LLGroupMgr::postGroupBanRequestCoro, this, cap_url, group_id,
+ action, ban_list, update));
+ break;
+ case REQUEST_PUT:
+ case REQUEST_DEL:
+ break;
+ }
}
-
void LLGroupMgr::processGroupBanRequest(const LLSD& content)
{
// Did we get anything in content?
@@ -1992,45 +2028,42 @@ void LLGroupMgr::processGroupBanRequest(const LLSD& content)
LLGroupMgr::getInstance()->notifyObservers(GC_BANLIST);
}
+void LLGroupMgr::groupMembersRequestCoro(std::string url, LLUUID groupId)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("groupMembersRequest", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
+ mMemberRequestInFlight = true;
-// Responder class for capability group management
-class GroupMemberDataResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(GroupMemberDataResponder);
-public:
- GroupMemberDataResponder() {}
- virtual ~GroupMemberDataResponder() {}
+ LLSD postData = LLSD::emptyMap();
+ postData["group_id"] = groupId;
-private:
- /* virtual */ void httpSuccess();
- /* virtual */ void httpFailure();
- LLSD mMemberData;
-};
+ LLSD result = httpAdapter->postAndYield(httpRequest, url, postData, httpOpts);
-void GroupMemberDataResponder::httpFailure()
-{
- LL_WARNS("GrpMgr") << "Error receiving group member data "
- << dumpResponse() << LL_ENDL;
-}
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-void GroupMemberDataResponder::httpSuccess()
-{
- const LLSD& content = getContent();
- if (!content.isMap())
- {
- failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
- return;
- }
- LLGroupMgr::processCapGroupMembersRequest(content);
-}
+ if (!status)
+ {
+ LL_WARNS("GrpMgr") << "Error receiving group member data " << LL_ENDL;
+ mMemberRequestInFlight = false;
+ return;
+ }
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ LLGroupMgr::processCapGroupMembersRequest(result);
+ mMemberRequestInFlight = false;
+}
-// static
void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id)
{
+ static U32 lastGroupMemberRequestFrame = 0;
+
// Have we requested the information already this frame?
- if(mLastGroupMembersRequestFrame == gFrameCount)
+ if ((lastGroupMemberRequestFrame == gFrameCount) || (mMemberRequestInFlight))
return;
LLViewerRegion* currentRegion = gAgent.getRegion();
@@ -2059,20 +2092,13 @@ void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id)
return;
}
- // Post to our service. Add a body containing the group_id.
- LLSD body = LLSD::emptyMap();
- body["group_id"] = group_id;
+ lastGroupMemberRequestFrame = gFrameCount;
- LLHTTPClient::ResponderPtr grp_data_responder = new GroupMemberDataResponder();
-
- // This could take a while to finish, timeout after 5 minutes.
- LLHTTPClient::post(cap_url, body, grp_data_responder, LLSD(), 300);
-
- mLastGroupMembersRequestFrame = gFrameCount;
+ LLCoros::instance().launch("LLGroupMgr::groupMembersRequestCoro",
+ boost::bind(&LLGroupMgr::groupMembersRequestCoro, this, cap_url, group_id));
}
-// static
void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
{
// Did we get anything in content?
@@ -2089,7 +2115,7 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
LLUUID group_id = content["group_id"].asUUID();
- LLGroupMgrGroupData* group_datap = LLGroupMgr::getInstance()->getGroupData(group_id);
+ LLGroupMgrGroupData* group_datap = getGroupData(group_id);
if(!group_datap)
{
LL_WARNS("GrpMgr") << "Received incorrect, possibly stale, group or request id" << LL_ENDL;
@@ -2183,7 +2209,7 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
// TODO:
// Refactor to reduce multiple calls for data we already have.
if(group_datap->mTitles.size() < 1)
- LLGroupMgr::getInstance()->sendGroupTitlesRequest(group_id);
+ sendGroupTitlesRequest(group_id);
group_datap->mMemberDataComplete = true;
@@ -2192,11 +2218,11 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
if (group_datap->mPendingRoleMemberRequest || !group_datap->mRoleMemberDataComplete)
{
group_datap->mPendingRoleMemberRequest = false;
- LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(group_id);
+ sendGroupRoleMembersRequest(group_id);
}
group_datap->mChanged = TRUE;
- LLGroupMgr::getInstance()->notifyObservers(GC_MEMBER_DATA);
+ notifyObservers(GC_MEMBER_DATA);
}
diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h
index 2e94e8d9a0..fd0c2de854 100755
--- a/indra/newview/llgroupmgr.h
+++ b/indra/newview/llgroupmgr.h
@@ -32,6 +32,8 @@
#include <vector>
#include <string>
#include <map>
+#include "lleventcoro.h"
+#include "llcoros.h"
// Forward Declarations
class LLMessageSystem;
@@ -362,6 +364,7 @@ public:
BAN_UPDATE = 4
};
+
public:
LLGroupMgr();
~LLGroupMgr();
@@ -396,15 +399,13 @@ public:
static void sendGroupMemberEjects(const LLUUID& group_id,
uuid_vec_t& member_ids);
- static void sendGroupBanRequest(EBanRequestType request_type,
+ void sendGroupBanRequest(EBanRequestType request_type,
const LLUUID& group_id,
U32 ban_action = BAN_NO_ACTION,
- const uuid_vec_t ban_list = uuid_vec_t());
+ const uuid_vec_t &ban_list = uuid_vec_t());
- static void processGroupBanRequest(const LLSD& content);
void sendCapGroupMembersRequest(const LLUUID& group_id);
- static void processCapGroupMembersRequest(const LLSD& content);
void cancelGroupRoleChanges(const LLUUID& group_id);
@@ -427,6 +428,14 @@ public:
void clearGroupData(const LLUUID& group_id);
private:
+ void groupMembersRequestCoro(std::string url, LLUUID groupId);
+ void processCapGroupMembersRequest(const LLSD& content);
+
+ void getGroupBanRequestCoro(std::string url, LLUUID groupId);
+ void postGroupBanRequestCoro(std::string url, LLUUID groupId, U32 action, uuid_vec_t banList, bool update);
+
+ static void processGroupBanRequest(const LLSD& content);
+
void notifyObservers(LLGroupChange gc);
void notifyObserver(const LLUUID& group_id, LLGroupChange gc);
void addGroup(LLGroupMgrGroupData* group_datap);
@@ -442,7 +451,7 @@ private:
typedef std::map<LLUUID,observer_set_t> observer_map_t;
observer_map_t mParticularObservers;
- S32 mLastGroupMembersRequestFrame;
+ bool mMemberRequestInFlight;
};
diff --git a/indra/newview/llhomelocationresponder.cpp b/indra/newview/llhomelocationresponder.cpp
deleted file mode 100755
index d0492bcdb4..0000000000
--- a/indra/newview/llhomelocationresponder.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
- * @file llhomelocationresponder.cpp
- * @author Meadhbh Hamrick
- * @brief Processes responses to the HomeLocation CapReq
- *
- * $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$
- */
-
-/* File Inclusions */
-#include "llviewerprecompiledheaders.h"
-
-#include "llhomelocationresponder.h"
-#include "llsdutil.h"
-#include "llagent.h"
-#include "llviewerregion.h"
-
-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 )
- {
- failureResult(HTTP_INTERNAL_ERROR, "Invalid server response content", content);
- }
- else
- {
- LL_INFOS() << "setting home position" << LL_ENDL;
-
- LLViewerRegion *viewer_region = gAgent.getRegion();
- gAgent.setHomePosRegion( viewer_region->getHandle(), agent_pos );
- }
-}
-
-void LLHomeLocationResponder::httpFailure()
-{
- LL_WARNS() << dumpResponse() << LL_ENDL;
-}
diff --git a/indra/newview/llhomelocationresponder.h b/indra/newview/llhomelocationresponder.h
deleted file mode 100755
index adc6c8cb58..0000000000
--- a/indra/newview/llhomelocationresponder.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * @file llhomelocationresponder.h
- * @author Meadhbh Hamrick
- * @brief Processes responses to the HomeLocation CapReq
- *
- * $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_LLHOMELOCATIONRESPONDER_H
-#define LL_LLHOMELOCATIONRESPONDER_H
-
-/* File Inclusions */
-#include "llhttpclient.h"
-
-/* Typedef, Enum, Class, Struct, etc. */
-class LLHomeLocationResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(LLHomeLocationResponder);
-private:
- /* virtual */ void httpSuccess();
- /* virtual */ void httpFailure();
-};
-
-#endif
diff --git a/indra/newview/llhttpretrypolicy.cpp b/indra/newview/llhttpretrypolicy.cpp
index 2d4ce6c883..e2e151eb63 100755
--- a/indra/newview/llhttpretrypolicy.cpp
+++ b/indra/newview/llhttpretrypolicy.cpp
@@ -56,7 +56,7 @@ bool LLAdaptiveRetryPolicy::getRetryAfter(const LLSD& headers, F32& retry_header
&& getSecondsUntilRetryAfter(headers[HTTP_IN_HEADER_RETRY_AFTER].asStringRef(), retry_header_time));
}
-bool LLAdaptiveRetryPolicy::getRetryAfter(const LLCore::HttpHeaders *headers, F32& retry_header_time)
+bool LLAdaptiveRetryPolicy::getRetryAfter(const LLCore::HttpHeaders::ptr_t &headers, F32& retry_header_time)
{
if (headers)
{
@@ -85,9 +85,9 @@ void LLAdaptiveRetryPolicy::onFailure(S32 status, const LLSD& headers)
void LLAdaptiveRetryPolicy::onFailure(const LLCore::HttpResponse *response)
{
F32 retry_header_time;
- const LLCore::HttpHeaders *headers = response->getHeaders();
+ const LLCore::HttpHeaders::ptr_t headers = response->getHeaders();
bool has_retry_header_time = getRetryAfter(headers,retry_header_time);
- onFailureCommon(response->getStatus().mType, has_retry_header_time, retry_header_time);
+ onFailureCommon(response->getStatus().getType(), has_retry_header_time, retry_header_time);
}
void LLAdaptiveRetryPolicy::onFailureCommon(S32 status, bool has_retry_header_time, F32 retry_header_time)
diff --git a/indra/newview/llhttpretrypolicy.h b/indra/newview/llhttpretrypolicy.h
index cf79e0b401..c0cc263546 100755
--- a/indra/newview/llhttpretrypolicy.h
+++ b/indra/newview/llhttpretrypolicy.h
@@ -79,7 +79,7 @@ public:
protected:
void init();
bool getRetryAfter(const LLSD& headers, F32& retry_header_time);
- bool getRetryAfter(const LLCore::HttpHeaders *headers, F32& retry_header_time);
+ bool getRetryAfter(const LLCore::HttpHeaders::ptr_t &headers, F32& retry_header_time);
void onFailureCommon(S32 status, bool has_retry_header_time, F32 retry_header_time);
private:
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 5d3a11e245..8d670d0b0a 100755
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -37,7 +37,6 @@
#include "llrect.h"
#include "llerror.h"
#include "llbutton.h"
-#include "llhttpclient.h"
#include "llsdutil_math.h"
#include "llstring.h"
#include "lltextutil.h"
@@ -69,6 +68,7 @@
#include "llconversationlog.h"
#include "message.h"
#include "llviewerregion.h"
+#include "llcorehttputil.h"
const static std::string ADHOC_NAME_SUFFIX(" Conference");
@@ -79,6 +79,10 @@ const static std::string NEARBY_P2P_BY_AGENT("nearby_P2P_by_agent");
/** Timeout of outgoing session initialization (in seconds) */
const static U32 SESSION_INITIALIZATION_TIMEOUT = 30;
+void startConfrenceCoro(std::string url, LLUUID tempSessionId, LLUUID creatorId, LLUUID otherParticipantId, LLSD agents);
+void chatterBoxInvitationCoro(std::string url, LLUUID sessionId, LLIMMgr::EInvitationType invitationType);
+void start_deprecated_conference_chat(const LLUUID& temp_session_id, const LLUUID& creator_id, const LLUUID& other_participant_id, const LLSD& agents_to_invite);
+
std::string LLCallDialogManager::sPreviousSessionlName = "";
LLIMModel::LLIMSession::SType LLCallDialogManager::sPreviousSessionType = LLIMModel::LLIMSession::P2P_SESSION;
std::string LLCallDialogManager::sCurrentSessionlName = "";
@@ -110,7 +114,7 @@ void process_dnd_im(const LLSD& notification)
{
LLSD data = notification["substitutions"];
LLUUID sessionID = data["SESSION_ID"].asUUID();
- LLUUID fromID = data["FROM_ID"].asUUID();
+ LLUUID fromID = data["FROM_ID"].asUUID();
//re-create the IM session if needed
//(when coming out of DND mode upon app restart)
@@ -131,12 +135,10 @@ void process_dnd_im(const LLSD& notification)
fromID,
false,
false); //will need slight refactor to retrieve whether offline message or not (assume online for now)
- }
-
- notify_of_message(data, true);
}
-
+ notify_of_message(data, true);
+}
static void on_avatar_name_cache_toast(const LLUUID& agent_id,
@@ -387,6 +389,130 @@ void on_new_message(const LLSD& msg)
notify_of_message(msg, false);
}
+void startConfrenceCoro(std::string url,
+ LLUUID tempSessionId, LLUUID creatorId, LLUUID otherParticipantId, LLSD agents)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLSD postData;
+ postData["method"] = "start conference";
+ postData["session-id"] = tempSessionId;
+ postData["params"] = agents;
+
+ LLSD result = httpAdapter->postAndYield(httpRequest, url, postData);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS("LLIMModel") << "Failed to start conference" << LL_ENDL;
+ //try an "old school" way.
+ // *TODO: What about other error status codes? 4xx 5xx?
+ if (status == LLCore::HttpStatus(HTTP_BAD_REQUEST))
+ {
+ start_deprecated_conference_chat(
+ tempSessionId,
+ creatorId,
+ otherParticipantId,
+ agents);
+ }
+
+ //else throw an error back to the client?
+ //in theory we should have just have these error strings
+ //etc. set up in this file as opposed to the IMMgr,
+ //but the error string were unneeded here previously
+ //and it is not worth the effort switching over all
+ //the possible different language translations
+ }
+}
+
+void chatterBoxInvitationCoro(std::string url, LLUUID sessionId, LLIMMgr::EInvitationType invitationType)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLSD postData;
+ postData["method"] = "accept invitation";
+ postData["session-id"] = sessionId;
+
+ LLSD result = httpAdapter->postAndYield(httpRequest, url, postData);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!gIMMgr)
+ {
+ LL_WARNS("") << "Global IM Manager is NULL" << LL_ENDL;
+ return;
+ }
+
+ if (!status)
+ {
+ LL_WARNS("LLIMModel") << "Bad HTTP response in chatterBoxInvitationCoro" << LL_ENDL;
+ //throw something back to the viewer here?
+
+ gIMMgr->clearPendingAgentListUpdates(sessionId);
+ gIMMgr->clearPendingInvitation(sessionId);
+
+ if (status == LLCore::HttpStatus(HTTP_NOT_FOUND))
+ {
+ static const std::string error_string("session_does_not_exist_error");
+ gIMMgr->showSessionStartError(error_string, sessionId);
+ }
+ return;
+ }
+
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+
+ LLIMSpeakerMgr* speakerMgr = LLIMModel::getInstance()->getSpeakerManager(sessionId);
+ if (speakerMgr)
+ {
+ //we've accepted our invitation
+ //and received a list of agents that were
+ //currently in the session when the reply was sent
+ //to us. Now, it is possible that there were some agents
+ //to slip in/out between when that message was sent to us
+ //and now.
+
+ //the agent list updates we've received have been
+ //accurate from the time we were added to the session
+ //but unfortunately, our base that we are receiving here
+ //may not be the most up to date. It was accurate at
+ //some point in time though.
+ speakerMgr->setSpeakers(result);
+
+ //we now have our base of users in the session
+ //that was accurate at some point, but maybe not now
+ //so now we apply all of the updates we've received
+ //in case of race conditions
+ speakerMgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(sessionId));
+ }
+
+ if (LLIMMgr::INVITATION_TYPE_VOICE == invitationType)
+ {
+ gIMMgr->startCall(sessionId, LLVoiceChannel::INCOMING_CALL);
+ }
+
+ if ((invitationType == LLIMMgr::INVITATION_TYPE_VOICE
+ || invitationType == LLIMMgr::INVITATION_TYPE_IMMEDIATE)
+ && LLIMModel::getInstance()->findIMSession(sessionId))
+ {
+ // TODO remove in 2010, for voice calls we do not open an IM window
+ //LLFloaterIMSession::show(mSessionID);
+ }
+
+ gIMMgr->clearPendingAgentListUpdates(sessionId);
+ gIMMgr->clearPendingInvitation(sessionId);
+
+}
+
+
LLIMModel::LLIMModel()
{
addNewMsgCallback(boost::bind(&LLFloaterIMSession::newIMCallback, _1));
@@ -1459,54 +1585,6 @@ void start_deprecated_conference_chat(
delete[] bucket;
}
-class LLStartConferenceChatResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(LLStartConferenceChatResponder);
-public:
- LLStartConferenceChatResponder(
- const LLUUID& temp_session_id,
- const LLUUID& creator_id,
- const LLUUID& other_participant_id,
- const LLSD& agents_to_invite)
- {
- mTempSessionID = temp_session_id;
- mCreatorID = creator_id;
- mOtherParticipantID = other_participant_id;
- mAgents = agents_to_invite;
- }
-
-protected:
- virtual void httpFailure()
- {
- //try an "old school" way.
- // *TODO: What about other error status codes? 4xx 5xx?
- if ( getStatus() == HTTP_BAD_REQUEST )
- {
- start_deprecated_conference_chat(
- mTempSessionID,
- mCreatorID,
- mOtherParticipantID,
- mAgents);
- }
-
- LL_WARNS() << dumpResponse() << LL_ENDL;
-
- //else throw an error back to the client?
- //in theory we should have just have these error strings
- //etc. set up in this file as opposed to the IMMgr,
- //but the error string were unneeded here previously
- //and it is not worth the effort switching over all
- //the possible different language translations
- }
-
-private:
- LLUUID mTempSessionID;
- LLUUID mCreatorID;
- LLUUID mOtherParticipantID;
-
- LLSD mAgents;
-};
-
// Returns true if any messages were sent, false otherwise.
// Is sort of equivalent to "does the server need to do anything?"
bool LLIMModel::sendStartSession(
@@ -1543,20 +1621,10 @@ bool LLIMModel::sendStartSession(
{
std::string url = region->getCapability(
"ChatSessionRequest");
- LLSD data;
- data["method"] = "start conference";
- data["session-id"] = temp_session_id;
-
- data["params"] = agents;
- LLHTTPClient::post(
- url,
- data,
- new LLStartConferenceChatResponder(
- temp_session_id,
- gAgent.getID(),
- other_participant_id,
- data["params"]));
+ LLCoros::instance().launch("startConfrenceCoro",
+ boost::bind(&startConfrenceCoro, url,
+ temp_session_id, gAgent.getID(), other_participant_id, agents));
}
else
{
@@ -1574,97 +1642,6 @@ bool LLIMModel::sendStartSession(
return false;
}
-//
-// Helper Functions
-//
-
-class LLViewerChatterBoxInvitationAcceptResponder :
- public LLHTTPClient::Responder
-{
- LOG_CLASS(LLViewerChatterBoxInvitationAcceptResponder);
-public:
- LLViewerChatterBoxInvitationAcceptResponder(
- const LLUUID& session_id,
- LLIMMgr::EInvitationType invitation_type)
- {
- mSessionID = session_id;
- mInvitiationType = invitation_type;
- }
-
-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);
- if (speaker_mgr)
- {
- //we've accepted our invitation
- //and received a list of agents that were
- //currently in the session when the reply was sent
- //to us. Now, it is possible that there were some agents
- //to slip in/out between when that message was sent to us
- //and now.
-
- //the agent list updates we've received have been
- //accurate from the time we were added to the session
- //but unfortunately, our base that we are receiving here
- //may not be the most up to date. It was accurate at
- //some point in time though.
- speaker_mgr->setSpeakers(content);
-
- //we now have our base of users in the session
- //that was accurate at some point, but maybe not now
- //so now we apply all of the udpates we've received
- //in case of race conditions
- speaker_mgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(mSessionID));
- }
-
- if (LLIMMgr::INVITATION_TYPE_VOICE == mInvitiationType)
- {
- gIMMgr->startCall(mSessionID, LLVoiceChannel::INCOMING_CALL);
- }
-
- if ((mInvitiationType == LLIMMgr::INVITATION_TYPE_VOICE
- || mInvitiationType == LLIMMgr::INVITATION_TYPE_IMMEDIATE)
- && LLIMModel::getInstance()->findIMSession(mSessionID))
- {
- // TODO remove in 2010, for voice calls we do not open an IM window
- //LLFloaterIMSession::show(mSessionID);
- }
-
- gIMMgr->clearPendingAgentListUpdates(mSessionID);
- gIMMgr->clearPendingInvitation(mSessionID);
- }
- }
-
- void httpFailure()
- {
- LL_WARNS() << dumpResponse() << LL_ENDL;
- //throw something back to the viewer here?
- if ( gIMMgr )
- {
- gIMMgr->clearPendingAgentListUpdates(mSessionID);
- gIMMgr->clearPendingInvitation(mSessionID);
- if ( HTTP_NOT_FOUND == getStatus() )
- {
- static const std::string error_string("session_does_not_exist_error");
- gIMMgr->showSessionStartError(error_string, mSessionID);
- }
- }
- }
-
-private:
- LLUUID mSessionID;
- LLIMMgr::EInvitationType mInvitiationType;
-};
-
// the other_participant_id is either an agent_id, a group_id, or an inventory
// folder item_id (collection of calling cards)
@@ -2490,15 +2467,9 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload
if (voice)
{
- LLSD data;
- data["method"] = "accept invitation";
- data["session-id"] = session_id;
- LLHTTPClient::post(
- url,
- data,
- new LLViewerChatterBoxInvitationAcceptResponder(
- session_id,
- inv_type));
+ LLCoros::instance().launch("chatterBoxInvitationCoro",
+ boost::bind(&chatterBoxInvitationCoro, url,
+ session_id, inv_type));
// send notification message to the corresponding chat
if (payload["notify_box_type"].asString() == "VoiceInviteGroup" || payload["notify_box_type"].asString() == "VoiceInviteAdHoc")
@@ -2533,10 +2504,10 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload
LLSD data;
data["method"] = "decline invitation";
data["session-id"] = session_id;
- LLHTTPClient::post(
- url,
- data,
- NULL);
+
+ LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, data,
+ "Invitation declined",
+ "Invitation decline failed.");
}
}
@@ -2583,15 +2554,9 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response)
std::string url = gAgent.getRegion()->getCapability(
"ChatSessionRequest");
- LLSD data;
- data["method"] = "accept invitation";
- data["session-id"] = session_id;
- LLHTTPClient::post(
- url,
- data,
- new LLViewerChatterBoxInvitationAcceptResponder(
- session_id,
- inv_type));
+ LLCoros::instance().launch("chatterBoxInvitationCoro",
+ boost::bind(&chatterBoxInvitationCoro, url,
+ session_id, inv_type));
}
}
break;
@@ -2621,10 +2586,9 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response)
LLSD data;
data["method"] = "decline invitation";
data["session-id"] = session_id;
- LLHTTPClient::post(
- url,
- data,
- NULL);
+ LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, data,
+ "Invitation declined.",
+ "Invitation decline failed.");
}
}
@@ -3681,15 +3645,9 @@ public:
if ( url != "" )
{
- LLSD data;
- data["method"] = "accept invitation";
- data["session-id"] = session_id;
- LLHTTPClient::post(
- url,
- data,
- new LLViewerChatterBoxInvitationAcceptResponder(
- session_id,
- LLIMMgr::INVITATION_TYPE_INSTANT_MESSAGE));
+ LLCoros::instance().launch("chatterBoxInvitationCoro",
+ boost::bind(&chatterBoxInvitationCoro, url,
+ session_id, LLIMMgr::INVITATION_TYPE_INSTANT_MESSAGE));
}
} //end if invitation has instant message
else if ( input["body"].has("voice") )
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index f92eff4845..41a8813acb 100755
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -34,6 +34,9 @@
#include "lllogchat.h"
#include "llvoicechannel.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
+
class LLAvatarName;
class LLFriendObserver;
class LLCallDialogManager;
@@ -292,6 +295,7 @@ private:
* Add message to a list of message associated with session specified by session_id
*/
bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text);
+
};
class LLIMSessionObserver
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index f92332dea5..47d3e88b3a 100755
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -148,8 +148,8 @@ LLInventoryModel::LLInventoryModel()
mObservers(),
mHttpRequestFG(NULL),
mHttpRequestBG(NULL),
- mHttpOptions(NULL),
- mHttpHeaders(NULL),
+ mHttpOptions(),
+ mHttpHeaders(),
mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
mHttpPriorityFG(0),
mHttpPriorityBG(0),
@@ -178,16 +178,9 @@ void LLInventoryModel::cleanupInventory()
mObservers.clear();
// Run down HTTP transport
- if (mHttpHeaders)
- {
- mHttpHeaders->release();
- mHttpHeaders = NULL;
- }
- if (mHttpOptions)
- {
- mHttpOptions->release();
- mHttpOptions = NULL;
- }
+ mHttpHeaders.reset();
+ mHttpOptions.reset();
+
delete mHttpRequestFG;
mHttpRequestFG = NULL;
delete mHttpRequestBG;
@@ -524,59 +517,6 @@ const LLUUID LLInventoryModel::findLibraryCategoryUUIDForType(LLFolderType::ETyp
return findCategoryUUIDForTypeInRoot(preferred_type, create_folder, gInventory.getLibraryRootFolderID());
}
-class LLCreateInventoryCategoryResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(LLCreateInventoryCategoryResponder);
-public:
- LLCreateInventoryCategoryResponder(LLInventoryModel* model,
- boost::optional<inventory_func_type> callback):
- mModel(model),
- mCallback(callback)
- {
- }
-
-protected:
- virtual void httpFailure()
- {
- LL_WARNS(LOG_INV) << dumpResponse() << LL_ENDL;
- }
-
- 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();
-
- LL_DEBUGS(LOG_INV) << ll_pretty_print_sd(content) << LL_ENDL;
- // Add the category to the internal representation
- LLPointer<LLViewerInventoryCategory> cat =
- new LLViewerInventoryCategory( category_id,
- content["parent_id"].asUUID(),
- (LLFolderType::EType)content["type"].asInteger(),
- content["name"].asString(),
- gAgent.getID() );
- cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL);
- cat->setDescendentCount(0);
- LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1);
- mModel->accountForUpdate(update);
- mModel->updateCategory(cat);
-
- if (mCallback)
- {
- mCallback.get()(category_id);
- }
- }
-
-private:
- boost::optional<inventory_func_type> mCallback;
- LLInventoryModel* mModel;
-};
-
// Convenience function to create a new category. You could call
// updateCategory() with a newly generated UUID category, but this
// version will take care of details like what the name should be
@@ -584,7 +524,7 @@ private:
LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,
LLFolderType::EType preferred_type,
const std::string& pname,
- boost::optional<inventory_func_type> callback)
+ inventory_func_type callback)
{
LLUUID id;
@@ -616,7 +556,7 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,
if ( viewer_region )
url = viewer_region->getCapability("CreateInventoryCategory");
- if (!url.empty() && callback.get_ptr())
+ if (!url.empty() && callback)
{
//Let's use the new capability.
@@ -630,11 +570,8 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,
request["payload"] = body;
LL_DEBUGS(LOG_INV) << "create category request: " << ll_pretty_print_sd(request) << LL_ENDL;
- // viewer_region->getCapAPI().post(request);
- LLHTTPClient::post(
- url,
- body,
- new LLCreateInventoryCategoryResponder(this, callback) );
+ LLCoros::instance().launch("LLInventoryModel::createNewCategoryCoro",
+ boost::bind(&LLInventoryModel::createNewCategoryCoro, this, url, body, callback));
return LLUUID::null;
}
@@ -663,6 +600,57 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,
return id;
}
+void LLInventoryModel::createNewCategoryCoro(std::string url, LLSD postData, inventory_func_type callback)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("createNewCategoryCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+
+ httpOpts->setWantHeaders(true);
+
+ LL_INFOS("HttpCoroutineAdapter", "genericPostCoro") << "Generic POST for " << url << LL_ENDL;
+
+ LLSD result = httpAdapter->postAndYield(httpRequest, url, postData, httpOpts);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS() << "HTTP failure attempting to create category." << LL_ENDL;
+ return;
+ }
+
+ if (!result.has("folder_id"))
+ {
+ LL_WARNS() << "Malformed response contents" << ll_pretty_print_sd(result) << LL_ENDL;
+ return;
+ }
+
+ LLUUID categoryId = result["folder_id"].asUUID();
+
+ // Add the category to the internal representation
+ LLPointer<LLViewerInventoryCategory> cat = new LLViewerInventoryCategory(categoryId,
+ result["parent_id"].asUUID(), (LLFolderType::EType)result["type"].asInteger(),
+ result["name"].asString(), gAgent.getID());
+
+ cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL);
+ cat->setDescendentCount(0);
+ LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1);
+
+ accountForUpdate(update);
+ updateCategory(cat);
+
+ if (callback)
+ {
+ callback(categoryId);
+ }
+
+}
+
// This is optimized for the case that we just want to know whether a
// category has any immediate children meeting a condition, without
// needing to recurse or build up any lists.
@@ -2423,11 +2411,11 @@ void LLInventoryModel::initHttpRequest()
mHttpRequestFG = new LLCore::HttpRequest;
mHttpRequestBG = new LLCore::HttpRequest;
- mHttpOptions = new LLCore::HttpOptions;
+ mHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
mHttpOptions->setTransferTimeout(300);
mHttpOptions->setUseRetryAfter(true);
// mHttpOptions->setTrace(2); // Do tracing of requests
- mHttpHeaders = new LLCore::HttpHeaders;
+ mHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders);
mHttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML);
mHttpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_LLSD_XML);
mHttpPolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_INVENTORY);
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index ac336e347c..e8977bc7d7 100755
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -46,6 +46,8 @@
#include "httpoptions.h"
#include "httpheaders.h"
#include "httphandler.h"
+#include "lleventcoro.h"
+#include "llcoros.h"
class LLInventoryObserver;
class LLInventoryObject;
@@ -207,14 +209,14 @@ private:
**/
//--------------------------------------------------------------------
- // Descendents
+ // Descendants
//--------------------------------------------------------------------
public:
- // Make sure we have the descendents in the structure. Returns true
+ // Make sure we have the descendants in the structure. Returns true
// if a fetch was performed.
bool fetchDescendentsOf(const LLUUID& folder_id) const;
- // Return the direct descendents of the id provided.Set passed
+ // Return the direct descendants of the id provided.Set passed
// in values to NULL if the call fails.
// NOTE: The array provided points straight into the guts of
// this object, and should only be used for read operations, since
@@ -223,10 +225,10 @@ public:
cat_array_t*& categories,
item_array_t*& items) const;
- // Compute a hash of direct descendent names (for detecting child name changes)
+ // Compute a hash of direct descendant names (for detecting child name changes)
LLMD5 hashDirectDescendentNames(const LLUUID& cat_id) const;
- // Starting with the object specified, add its descendents to the
+ // Starting with the object specified, add its descendants to the
// array provided, but do not add the inventory object specified
// by id. There is no guaranteed order.
// NOTE: Neither array will be erased before adding objects to it.
@@ -340,7 +342,7 @@ public:
U32 updateItem(const LLViewerInventoryItem* item, U32 mask = 0);
// Change an existing item with the matching id or add
- // the category. No notifcation will be sent to observers. This
+ // the category. No notification will be sent to observers. This
// method will only generate network traffic if the item had to be
// reparented.
// NOTE: In usage, you will want to perform cache accounting
@@ -378,7 +380,7 @@ public:
bool update_parent_version = true,
bool do_notify_observers = true);
- // Update model after all descendents removed from server.
+ // Update model after all descendants removed from server.
void onDescendentsPurgedFromServer(const LLUUID& object_id, bool fix_broken_links = true);
// Update model after an existing item gets updated on server.
@@ -409,7 +411,7 @@ public:
// Changes items order by insertion of the item identified by src_item_id
// before (or after) the item identified by dest_item_id. Both items must exist in items array.
// Sorting is stored after method is finished. Only src_item_id is moved before (or after) dest_item_id.
- // The parameter "insert_before" controls on which side of dest_item_id src_item_id gets rensinserted.
+ // The parameter "insert_before" controls on which side of dest_item_id src_item_id gets reinserted.
static void updateItemsOrder(LLInventoryModel::item_array_t& items,
const LLUUID& src_item_id,
const LLUUID& dest_item_id,
@@ -433,7 +435,7 @@ public:
LLUUID createNewCategory(const LLUUID& parent_id,
LLFolderType::EType preferred_type,
const std::string& name,
- boost::optional<inventory_func_type> callback = boost::optional<inventory_func_type>());
+ inventory_func_type callback = NULL);
protected:
// Internal methods that add inventory and make sure that all of
// the internal data structures are consistent. These methods
@@ -441,6 +443,8 @@ protected:
// instance will take over the memory management from there.
void addCategory(LLViewerInventoryCategory* category);
void addItem(LLViewerInventoryItem* item);
+
+ void createNewCategoryCoro(std::string url, LLSD postData, inventory_func_type callback);
/** Mutators
** **
@@ -567,8 +571,8 @@ private:
// Usual plumbing for LLCore:: HTTP operations.
LLCore::HttpRequest * mHttpRequestFG;
LLCore::HttpRequest * mHttpRequestBG;
- LLCore::HttpOptions * mHttpOptions;
- LLCore::HttpHeaders * mHttpHeaders;
+ LLCore::HttpOptions::ptr_t mHttpOptions;
+ LLCore::HttpHeaders::ptr_t mHttpHeaders;
LLCore::HttpRequest::policy_t mHttpPolicyClass;
LLCore::HttpRequest::priority_t mHttpPriorityFG;
LLCore::HttpRequest::priority_t mHttpPriorityBG;
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 4a7a4e268d..38c4382654 100755
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -36,7 +36,9 @@
#include "llviewercontrol.h"
#include "llviewermedia.h"
#include "llviewernetwork.h"
-
+#include "lleventcoro.h"
+#include "llcoros.h"
+#include "llcorehttputil.h"
//
// Helpers
@@ -117,11 +119,76 @@ namespace LLMarketplaceImport
static S32 sImportResultStatus = 0;
static LLSD sImportResults = LLSD::emptyMap();
+#if 0
static LLTimer slmGetTimer;
static LLTimer slmPostTimer;
-
+#endif
// Responders
-
+
+#if 1
+ void marketplacePostCoro(std::string url)
+ {
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("marketplacePostCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+ httpOpts->setWantHeaders(true);
+ httpOpts->setFollowRedirects(true);
+
+ httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, "*/*");
+ httpHeaders->append(HTTP_OUT_HEADER_CONNECTION, "Keep-Alive");
+ httpHeaders->append(HTTP_OUT_HEADER_COOKIE, sMarketplaceCookie);
+ httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_XML);
+ httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, LLViewerMedia::getCurrentUserAgent());
+
+ LLSD result = httpAdapter->postAndYield(httpRequest, url, LLSD(), httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ S32 httpCode = status.getType();
+ if ((httpCode == MarketplaceErrorCodes::IMPORT_REDIRECT) ||
+ (httpCode == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) ||
+ // MAINT-2301 : we determined we can safely ignore that error in that context
+ (httpCode == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT))
+ {
+ if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
+ {
+ LL_INFOS() << " SLM POST : Ignoring time out status and treating it as success" << LL_ENDL;
+ }
+ httpCode = MarketplaceErrorCodes::IMPORT_DONE;
+ }
+
+ if (httpCode >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST)
+ {
+ if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
+ {
+ LL_INFOS() << " SLM POST clearing marketplace cookie due to client or server error" << LL_ENDL;
+ }
+ sMarketplaceCookie.clear();
+ }
+
+ sImportInProgress = (httpCode == MarketplaceErrorCodes::IMPORT_DONE);
+ sImportPostPending = false;
+ sImportResultStatus = httpCode;
+
+ {
+ std::stringstream str;
+ LLSDSerialize::toPrettyXML(result, str);
+
+ LL_INFOS() << "Full results:\n" << str.str() << "\n" << LL_ENDL;
+ }
+
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ sImportId = result;
+
+ }
+
+
+#else
class LLImportPostResponder : public LLHTTPClient::Responder
{
LOG_CLASS(LLImportPostResponder);
@@ -167,7 +234,75 @@ namespace LLMarketplaceImport
sImportId = getContent();
}
};
-
+#endif
+
+#if 1
+ void marketplaceGetCoro(std::string url, bool buildHeaders)
+ {
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("marketplaceGetCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+ httpOpts->setWantHeaders(true);
+ httpOpts->setFollowRedirects(!sMarketplaceCookie.empty());
+
+ if (buildHeaders)
+ {
+ httpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders);
+
+ httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, "*/*");
+ httpHeaders->append(HTTP_OUT_HEADER_COOKIE, sMarketplaceCookie);
+ httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML);
+ httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, LLViewerMedia::getCurrentUserAgent());
+ }
+ else
+ {
+ httpHeaders = LLViewerMedia::getHttpHeaders();
+ }
+
+ LLSD result = httpAdapter->getAndYield(httpRequest, url, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+ LLSD resultHeaders = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
+
+ if (sMarketplaceCookie.empty() && resultHeaders.has(HTTP_IN_HEADER_SET_COOKIE))
+ {
+ sMarketplaceCookie = resultHeaders[HTTP_IN_HEADER_SET_COOKIE].asString();
+ }
+
+ // MAINT-2452 : Do not clear the cookie on IMPORT_DONE_WITH_ERRORS : Happens when trying to import objects with wrong permissions
+ // ACME-1221 : Do not clear the cookie on IMPORT_NOT_FOUND : Happens for newly created Merchant accounts that are initially empty
+ S32 httpCode = status.getType();
+ if ((httpCode >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST) &&
+ (httpCode != MarketplaceErrorCodes::IMPORT_DONE_WITH_ERRORS) &&
+ (httpCode != MarketplaceErrorCodes::IMPORT_NOT_FOUND))
+ {
+ if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
+ {
+ LL_INFOS() << " SLM GET clearing marketplace cookie due to client or server error" << LL_ENDL;
+ }
+ sMarketplaceCookie.clear();
+ }
+ else if (gSavedSettings.getBOOL("InventoryOutboxLogging") && (httpCode >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST))
+ {
+ LL_INFOS() << " SLM GET : Got error status = " << httpCode << ", but marketplace cookie not cleared." << LL_ENDL;
+ }
+
+ sImportInProgress = (httpCode == MarketplaceErrorCodes::IMPORT_PROCESSING);
+ sImportGetPending = false;
+ sImportResultStatus = httpCode;
+
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ sImportResults = result;
+
+
+ }
+
+#else
class LLImportGetResponder : public LLHTTPClient::Responder
{
LOG_CLASS(LLImportGetResponder);
@@ -193,7 +328,7 @@ namespace LLMarketplaceImport
}
// MAINT-2452 : Do not clear the cookie on IMPORT_DONE_WITH_ERRORS : Happens when trying to import objects with wrong permissions
- // ACME-1221 : Do not clear the cookie on IMPORT_NOT_FOUND : Happens for newly created Merchant accounts that are initally empty
+ // ACME-1221 : Do not clear the cookie on IMPORT_NOT_FOUND : Happens for newly created Merchant accounts that are initially empty
S32 status = getStatus();
if ((status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST) &&
(status != MarketplaceErrorCodes::IMPORT_DONE_WITH_ERRORS) &&
@@ -216,6 +351,7 @@ namespace LLMarketplaceImport
sImportResults = getContent();
}
};
+#endif
// Basic API
@@ -266,8 +402,13 @@ namespace LLMarketplaceImport
sImportGetPending = true;
std::string url = getInventoryImportURL();
-
- if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
+
+#if 1
+ LLCoros::instance().launch("marketplaceGetCoro",
+ boost::bind(&marketplaceGetCoro, url, false));
+
+#else
+ if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
{
LL_INFOS() << " SLM GET: establishMarketplaceSessionCookie, LLHTTPClient::get, url = " << url << LL_ENDL;
LLSD headers = LLViewerMedia::getHeaders();
@@ -279,7 +420,7 @@ namespace LLMarketplaceImport
slmGetTimer.start();
LLHTTPClient::get(url, new LLImportGetResponder(), LLViewerMedia::getHeaders());
-
+#endif
return true;
}
@@ -296,6 +437,11 @@ namespace LLMarketplaceImport
url += sImportId.asString();
+#if 1
+ LLCoros::instance().launch("marketplaceGetCoro",
+ boost::bind(&marketplaceGetCoro, url, true));
+
+#else
// Make the headers for the post
LLSD headers = LLSD::emptyMap();
headers[HTTP_OUT_HEADER_ACCEPT] = "*/*";
@@ -315,7 +461,7 @@ namespace LLMarketplaceImport
slmGetTimer.start();
LLHTTPClient::get(url, new LLImportGetResponder(), headers);
-
+#endif
return true;
}
@@ -334,6 +480,11 @@ namespace LLMarketplaceImport
std::string url = getInventoryImportURL();
+#if 1
+ LLCoros::instance().launch("marketplacePostCoro",
+ boost::bind(&marketplacePostCoro, url));
+
+#else
// Make the headers for the post
LLSD headers = LLSD::emptyMap();
headers[HTTP_OUT_HEADER_ACCEPT] = "*/*";
@@ -353,7 +504,7 @@ namespace LLMarketplaceImport
slmPostTimer.start();
LLHTTPClient::post(url, LLSD(), new LLImportPostResponder(), headers);
-
+#endif
return true;
}
}
@@ -362,7 +513,6 @@ namespace LLMarketplaceImport
//
// Interface class
//
-
static const F32 MARKET_IMPORTER_UPDATE_FREQUENCY = 1.0f;
//static
diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp
index a1f6a01aa0..1045def72e 100755
--- a/indra/newview/llmaterialmgr.cpp
+++ b/indra/newview/llmaterialmgr.cpp
@@ -36,6 +36,9 @@
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
#include "llworld.h"
+#include "llhttpsdhandler.h"
+#include "httpcommon.h"
+#include "llcorehttputil.h"
/**
* Materials cap parameters
@@ -59,56 +62,51 @@
#define MATERIALS_PUT_THROTTLE_SECS 1.f
#define MATERIALS_PUT_MAX_ENTRIES 50
-/**
- * LLMaterialsResponder helper class
- */
-class LLMaterialsResponder : public LLHTTPClient::Responder
+
+class LLMaterialHttpHandler : public LLHttpSDHandler
{
-public:
- typedef boost::function<void (bool, const LLSD&)> CallbackFunction;
+public:
+ typedef boost::function<void(bool, const LLSD&)> CallbackFunction;
+ typedef boost::shared_ptr<LLMaterialHttpHandler> ptr_t;
+
+ LLMaterialHttpHandler(const std::string& method, CallbackFunction cback);
- LLMaterialsResponder(const std::string& pMethod, const std::string& pCapabilityURL, CallbackFunction pCallback);
- virtual ~LLMaterialsResponder();
+ virtual ~LLMaterialHttpHandler();
- virtual void httpSuccess();
- virtual void httpFailure();
+protected:
+ virtual void onSuccess(LLCore::HttpResponse * response, const LLSD &content);
+ virtual void onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status);
private:
std::string mMethod;
- std::string mCapabilityURL;
CallbackFunction mCallback;
};
-LLMaterialsResponder::LLMaterialsResponder(const std::string& pMethod, const std::string& pCapabilityURL, CallbackFunction pCallback)
- : LLHTTPClient::Responder()
- , mMethod(pMethod)
- , mCapabilityURL(pCapabilityURL)
- , mCallback(pCallback)
+LLMaterialHttpHandler::LLMaterialHttpHandler(const std::string& method, CallbackFunction cback):
+ LLHttpSDHandler(),
+ mMethod(method),
+ mCallback(cback)
{
+
}
-LLMaterialsResponder::~LLMaterialsResponder()
+LLMaterialHttpHandler::~LLMaterialHttpHandler()
{
}
-void LLMaterialsResponder::httpSuccess()
+void LLMaterialHttpHandler::onSuccess(LLCore::HttpResponse * response, const LLSD &content)
{
- const LLSD& pContent = getContent();
-
LL_DEBUGS("Materials") << LL_ENDL;
- mCallback(true, pContent);
+ mCallback(true, content);
}
-void LLMaterialsResponder::httpFailure()
+void LLMaterialHttpHandler::onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status)
{
- U32 pStatus = (U32) getStatus();
- const std::string& pReason = getReason();
-
LL_WARNS("Materials")
<< "\n--------------------------------------------------------------------------\n"
- << mMethod << " Error[" << pStatus << "] cannot access cap '" << MATERIALS_CAPABILITY_NAME
- << "'\n with url '" << mCapabilityURL << "' because " << pReason
+ << mMethod << " Error[" << status.toULong() << "] cannot access cap '" << MATERIALS_CAPABILITY_NAME
+ << "'\n with url '" << response->getRequestURL() << "' because " << status.toString()
<< "\n--------------------------------------------------------------------------"
<< LL_ENDL;
@@ -116,12 +114,35 @@ void LLMaterialsResponder::httpFailure()
mCallback(false, emptyResult);
}
+
+
/**
* LLMaterialMgr class
*/
-
-LLMaterialMgr::LLMaterialMgr()
+LLMaterialMgr::LLMaterialMgr():
+ mGetQueue(),
+ mGetPending(),
+ mGetCallbacks(),
+ mGetTECallbacks(),
+ mGetAllQueue(),
+ mGetAllRequested(),
+ mGetAllPending(),
+ mGetAllCallbacks(),
+ mPutQueue(),
+ mMaterials(),
+ mHttpRequest(),
+ mHttpHeaders(),
+ mHttpOptions(),
+ mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID),
+ mHttpPriority(0)
{
+ LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp());
+
+ mHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest());
+ mHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders());
+ mHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions());
+ mHttpPolicy = app_core_http.getPolicy(LLAppCoreHttp::AP_MATERIALS);
+
mMaterials.insert(std::pair<LLMaterialID, LLMaterialPtr>(LLMaterialID::null, LLMaterialPtr(NULL)));
gIdleCallbacks.addFunction(&LLMaterialMgr::onIdle, NULL);
LLWorld::instance().setRegionRemovedCallback(boost::bind(&LLMaterialMgr::onRegionRemoved, this, _1));
@@ -554,6 +575,8 @@ void LLMaterialMgr::onIdle(void*)
{
instancep->processPutQueue();
}
+
+ instancep->mHttpRequest->update(0L);
}
void LLMaterialMgr::processGetQueue()
@@ -629,10 +652,26 @@ void LLMaterialMgr::processGetQueue()
LLSD postData = LLSD::emptyMap();
postData[MATERIALS_CAP_ZIP_FIELD] = materialBinary;
- LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("POST", capURL, boost::bind(&LLMaterialMgr::onGetResponse, this, _1, _2, region_id));
- LL_DEBUGS("Materials") << "POSTing to region '" << regionp->getName() << "' at '"<< capURL << " for " << materialsData.size() << " materials."
+ LLMaterialHttpHandler * handler =
+ new LLMaterialHttpHandler("POST",
+ boost::bind(&LLMaterialMgr::onGetResponse, this, _1, _2, region_id)
+ );
+
+ LL_DEBUGS("Materials") << "POSTing to region '" << regionp->getName() << "' at '" << capURL << " for " << materialsData.size() << " materials."
<< "\ndata: " << ll_pretty_print_sd(materialsData) << LL_ENDL;
- LLHTTPClient::post(capURL, postData, materialsResponder);
+
+ LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest,
+ mHttpPolicy, mHttpPriority, capURL,
+ postData, mHttpOptions, mHttpHeaders, handler);
+
+ if (handle == LLCORE_HTTP_HANDLE_INVALID)
+ {
+ delete handler;
+ LLCore::HttpStatus status = mHttpRequest->getStatus();
+ LL_ERRS("Meterials") << "Failed to execute material POST. Status = " <<
+ status.toULong() << "\"" << status.toString() << "\"" << LL_ENDL;
+ }
+
regionp->resetMaterialsCapThrottle();
}
}
@@ -667,8 +706,22 @@ void LLMaterialMgr::processGetAllQueue()
}
LL_DEBUGS("Materials") << "GET all for region " << region_id << "url " << capURL << LL_ENDL;
- LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("GET", capURL, boost::bind(&LLMaterialMgr::onGetAllResponse, this, _1, _2, *itRegion));
- LLHTTPClient::get(capURL, materialsResponder);
+ LLMaterialHttpHandler *handler =
+ new LLMaterialHttpHandler("GET",
+ boost::bind(&LLMaterialMgr::onGetAllResponse, this, _1, _2, *itRegion)
+ );
+
+ LLCore::HttpHandle handle = mHttpRequest->requestGet(mHttpPolicy, mHttpPriority, capURL,
+ mHttpOptions, mHttpHeaders, handler);
+
+ if (handle == LLCORE_HTTP_HANDLE_INVALID)
+ {
+ delete handler;
+ LLCore::HttpStatus status = mHttpRequest->getStatus();
+ LL_ERRS("Meterials") << "Failed to execute material GET. Status = " <<
+ status.toULong() << "\"" << status.toString() << "\"" << LL_ENDL;
+ }
+
regionp->resetMaterialsCapThrottle();
mGetAllPending.insert(std::pair<LLUUID, F64>(region_id, LLFrameTimer::getTotalSeconds()));
mGetAllQueue.erase(itRegion); // Invalidates region_id
@@ -755,8 +808,24 @@ void LLMaterialMgr::processPutQueue()
putData[MATERIALS_CAP_ZIP_FIELD] = materialBinary;
LL_DEBUGS("Materials") << "put for " << itRequest->second.size() << " faces to region " << itRequest->first->getName() << LL_ENDL;
- LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("PUT", capURL, boost::bind(&LLMaterialMgr::onPutResponse, this, _1, _2));
- LLHTTPClient::put(capURL, putData, materialsResponder);
+
+ LLMaterialHttpHandler * handler =
+ new LLMaterialHttpHandler("PUT",
+ boost::bind(&LLMaterialMgr::onPutResponse, this, _1, _2)
+ );
+
+ LLCore::HttpHandle handle = LLCoreHttpUtil::requestPutWithLLSD(
+ mHttpRequest, mHttpPolicy, mHttpPriority, capURL,
+ putData, mHttpOptions, mHttpHeaders, handler);
+
+ if (handle == LLCORE_HTTP_HANDLE_INVALID)
+ {
+ delete handler;
+ LLCore::HttpStatus status = mHttpRequest->getStatus();
+ LL_ERRS("Meterials") << "Failed to execute material PUT. Status = " <<
+ status.toULong() << "\"" << status.toString() << "\"" << LL_ENDL;
+ }
+
regionp->resetMaterialsCapThrottle();
}
else
diff --git a/indra/newview/llmaterialmgr.h b/indra/newview/llmaterialmgr.h
index e83f1f4e01..ef202d24ba 100644
--- a/indra/newview/llmaterialmgr.h
+++ b/indra/newview/llmaterialmgr.h
@@ -30,6 +30,9 @@
#include "llmaterial.h"
#include "llmaterialid.h"
#include "llsingleton.h"
+#include "httprequest.h"
+#include "httpheaders.h"
+#include "httpoptions.h"
class LLViewerRegion;
@@ -56,7 +59,7 @@ public:
void put(const LLUUID& object_id, const U8 te, const LLMaterial& material);
void remove(const LLUUID& object_id, const U8 te);
-protected:
+private:
void clearGetQueues(const LLUUID& region_id);
bool isGetPending(const LLUUID& region_id, const LLMaterialID& material_id) const;
bool isGetAllPending(const LLUUID& region_id) const;
@@ -72,16 +75,7 @@ protected:
void onPutResponse(bool success, const LLSD& content);
void onRegionRemoved(LLViewerRegion* regionp);
-protected:
- typedef std::set<LLMaterialID> material_queue_t;
- typedef std::map<LLUUID, material_queue_t> get_queue_t;
- get_queue_t mGetQueue;
- typedef std::pair<const LLUUID, LLMaterialID> pending_material_t;
- typedef std::map<const pending_material_t, F64> get_pending_map_t;
- get_pending_map_t mGetPending;
- typedef std::map<LLMaterialID, get_callback_t*> get_callback_map_t;
- get_callback_map_t mGetCallbacks;
-
+private:
// struct for TE-specific material ID query
class TEMaterialPair
{
@@ -108,22 +102,37 @@ protected:
bool operator()(const TEMaterialPair& left, const TEMaterialPair& right) const { return left < right; }
};
- typedef boost::unordered_map<TEMaterialPair, get_callback_te_t*, TEMaterialPairHasher> get_callback_te_map_t;
- get_callback_te_map_t mGetTECallbacks;
+ typedef std::set<LLMaterialID> material_queue_t;
+ typedef std::map<LLUUID, material_queue_t> get_queue_t;
+ typedef std::pair<const LLUUID, LLMaterialID> pending_material_t;
+ typedef std::map<const pending_material_t, F64> get_pending_map_t;
+ typedef std::map<LLMaterialID, get_callback_t*> get_callback_map_t;
+
+ typedef boost::unordered_map<TEMaterialPair, get_callback_te_t*, TEMaterialPairHasher> get_callback_te_map_t;
typedef std::set<LLUUID> getall_queue_t;
- getall_queue_t mGetAllQueue;
- getall_queue_t mGetAllRequested;
typedef std::map<LLUUID, F64> getall_pending_map_t;
- getall_pending_map_t mGetAllPending;
typedef std::map<LLUUID, getall_callback_t*> getall_callback_map_t;
- getall_callback_map_t mGetAllCallbacks;
-
typedef std::map<U8, LLMaterial> facematerial_map_t;
typedef std::map<LLUUID, facematerial_map_t> put_queue_t;
- put_queue_t mPutQueue;
- material_map_t mMaterials;
+ get_queue_t mGetQueue;
+ get_pending_map_t mGetPending;
+ get_callback_map_t mGetCallbacks;
+
+ get_callback_te_map_t mGetTECallbacks;
+ getall_queue_t mGetAllQueue;
+ getall_queue_t mGetAllRequested;
+ getall_pending_map_t mGetAllPending;
+ getall_callback_map_t mGetAllCallbacks;
+ put_queue_t mPutQueue;
+ material_map_t mMaterials;
+
+ LLCore::HttpRequest::ptr_t mHttpRequest;
+ LLCore::HttpHeaders::ptr_t mHttpHeaders;
+ LLCore::HttpOptions::ptr_t mHttpOptions;
+ LLCore::HttpRequest::policy_t mHttpPolicy;
+ LLCore::HttpRequest::priority_t mHttpPriority;
U32 getMaxEntries(const LLViewerRegion* regionp);
};
diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp
index 2fb9e60b29..b8ff76aa6d 100755
--- a/indra/newview/llmediadataclient.cpp
+++ b/indra/newview/llmediadataclient.cpp
@@ -33,6 +33,7 @@
#pragma warning (disable:4702)
#endif
+#include <algorithm>
#include <boost/lexical_cast.hpp>
#include "llhttpconstants.h"
@@ -40,6 +41,7 @@
#include "llmediaentry.h"
#include "lltextureentry.h"
#include "llviewerregion.h"
+#include "llcorehttputil.h"
//
// When making a request
@@ -91,52 +93,74 @@ const U32 LLMediaDataClient::MAX_ROUND_ROBIN_QUEUE_SIZE = 10000;
std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::request_queue_t &q);
std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::Request &q);
-template <typename T>
-typename T::iterator find_matching_request(T &c, const LLMediaDataClient::Request *request, LLMediaDataClient::Request::Type match_type)
+
+//=========================================================================
+/// Uniary Predicate for matching requests in collections by either the request
+/// or by UUID
+///
+class PredicateMatchRequest
{
- for(typename T::iterator iter = c.begin(); iter != c.end(); ++iter)
- {
- if(request->isMatch(*iter, match_type))
- {
- return iter;
- }
- }
-
- return c.end();
+public:
+ PredicateMatchRequest(const LLMediaDataClient::Request::ptr_t &request, LLMediaDataClient::Request::Type matchType = LLMediaDataClient::Request::ANY);
+ PredicateMatchRequest(const LLUUID &id, LLMediaDataClient::Request::Type matchType = LLMediaDataClient::Request::ANY);
+
+ PredicateMatchRequest(const PredicateMatchRequest &other);
+
+ bool operator()(const LLMediaDataClient::Request::ptr_t &test) const;
+
+private:
+ LLMediaDataClient::Request::ptr_t mRequest;
+ LLMediaDataClient::Request::Type mMatchType;
+ LLUUID mId;
+};
+
+
+PredicateMatchRequest::PredicateMatchRequest(const LLMediaDataClient::Request::ptr_t &request, LLMediaDataClient::Request::Type matchType) :
+ mRequest(request),
+ mMatchType(matchType),
+ mId()
+{}
+
+PredicateMatchRequest::PredicateMatchRequest(const LLUUID &id, LLMediaDataClient::Request::Type matchType) :
+ mRequest(),
+ mMatchType(matchType),
+ mId(id)
+{}
+
+PredicateMatchRequest::PredicateMatchRequest(const PredicateMatchRequest &other)
+{
+ mRequest = other.mRequest;
+ mMatchType = other.mMatchType;
+ mId = other.mId;
}
-template <typename T>
-typename T::iterator find_matching_request(T &c, const LLUUID &id, LLMediaDataClient::Request::Type match_type)
+bool PredicateMatchRequest::operator()(const LLMediaDataClient::Request::ptr_t &test) const
{
- for(typename T::iterator iter = c.begin(); iter != c.end(); ++iter)
- {
- if(((*iter)->getID() == id) && ((match_type == LLMediaDataClient::Request::ANY) || (match_type == (*iter)->getType())))
- {
- return iter;
- }
- }
-
- return c.end();
+ if (mRequest)
+ return (mRequest->isMatch(test, mMatchType));
+ else if (!mId.isNull())
+ return ((test->getID() == mId) && ((mMatchType == LLMediaDataClient::Request::ANY) || (mMatchType == test->getType())));
+ return false;
}
-// NOTE: remove_matching_requests will not work correctly for containers where deleting an element may invalidate iterators
-// to other elements in the container (such as std::vector).
-// If the implementation is changed to use a container with this property, this will need to be revisited.
+//=========================================================================
+///
template <typename T>
-void remove_matching_requests(T &c, const LLUUID &id, LLMediaDataClient::Request::Type match_type)
+void mark_dead_and_remove_if(T &c, const PredicateMatchRequest &matchPred)
{
- for(typename T::iterator iter = c.begin(); iter != c.end();)
- {
- typename T::value_type i = *iter;
- typename T::iterator next = iter;
- next++;
- if((i->getID() == id) && ((match_type == LLMediaDataClient::Request::ANY) || (match_type == i->getType())))
- {
- i->markDead();
- c.erase(iter);
- }
- iter = next;
- }
+ for (typename T::iterator it = c.begin(); it != c.end();)
+ {
+ if (matchPred(*it))
+ {
+ (*it)->markDead();
+ // *TDOO: When C++11 is in change the following line to: it = c.erase(it);
+ c.erase(it++);
+ }
+ else
+ {
+ ++it;
+ }
+ }
}
//////////////////////////////////////////////////////////////////////////////////////
@@ -145,18 +169,20 @@ void remove_matching_requests(T &c, const LLUUID &id, LLMediaDataClient::Request
//
//////////////////////////////////////////////////////////////////////////////////////
-LLMediaDataClient::LLMediaDataClient(F32 queue_timer_delay,
- F32 retry_timer_delay,
- U32 max_retries,
- U32 max_sorted_queue_size,
- U32 max_round_robin_queue_size)
- : mQueueTimerDelay(queue_timer_delay),
- mRetryTimerDelay(retry_timer_delay),
- mMaxNumRetries(max_retries),
- mMaxSortedQueueSize(max_sorted_queue_size),
- mMaxRoundRobinQueueSize(max_round_robin_queue_size),
- mQueueTimerIsRunning(false)
+LLMediaDataClient::LLMediaDataClient(F32 queue_timer_delay, F32 retry_timer_delay,
+ U32 max_retries, U32 max_sorted_queue_size, U32 max_round_robin_queue_size):
+ mQueueTimerDelay(queue_timer_delay),
+ mRetryTimerDelay(retry_timer_delay),
+ mMaxNumRetries(max_retries),
+ mMaxSortedQueueSize(max_sorted_queue_size),
+ mMaxRoundRobinQueueSize(max_round_robin_queue_size),
+ mQueueTimerIsRunning(false),
+ mHttpRequest(new LLCore::HttpRequest()),
+ mHttpHeaders(new LLCore::HttpHeaders()),
+ mHttpOpts(new LLCore::HttpOptions()),
+ mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID)
{
+ // *TODO: Look up real Policy ID
}
LLMediaDataClient::~LLMediaDataClient()
@@ -171,20 +197,23 @@ bool LLMediaDataClient::isEmpty() const
bool LLMediaDataClient::isInQueue(const LLMediaDataClientObject::ptr_t &object)
{
- if(find_matching_request(mQueue, object->getID(), LLMediaDataClient::Request::ANY) != mQueue.end())
- return true;
-
- if(find_matching_request(mUnQueuedRequests, object->getID(), LLMediaDataClient::Request::ANY) != mUnQueuedRequests.end())
- return true;
-
+ PredicateMatchRequest upred(object->getID());
+
+ if (std::find_if(mQueue.begin(), mQueue.end(), upred) != mQueue.end())
+ return true;
+ if (std::find_if(mUnQueuedRequests.begin(), mUnQueuedRequests.end(), upred) != mUnQueuedRequests.end())
+ return true;
+
return false;
}
void LLMediaDataClient::removeFromQueue(const LLMediaDataClientObject::ptr_t &object)
{
LL_DEBUGS("LLMediaDataClient") << "removing requests matching ID " << object->getID() << LL_ENDL;
- remove_matching_requests(mQueue, object->getID(), LLMediaDataClient::Request::ANY);
- remove_matching_requests(mUnQueuedRequests, object->getID(), LLMediaDataClient::Request::ANY);
+ PredicateMatchRequest upred(object->getID());
+
+ mark_dead_and_remove_if(mQueue, upred);
+ mark_dead_and_remove_if(mUnQueuedRequests, upred);
}
void LLMediaDataClient::startQueueTimer()
@@ -207,23 +236,24 @@ void LLMediaDataClient::stopQueueTimer()
bool LLMediaDataClient::processQueueTimer()
{
- if(isEmpty())
+ if (isDoneProcessing())
return true;
LL_DEBUGS("LLMediaDataClient") << "QueueTimer::tick() started, queue size is: " << mQueue.size() << LL_ENDL;
LL_DEBUGS("LLMediaDataClientQueue") << "QueueTimer::tick() started, SORTED queue is: " << mQueue << LL_ENDL;
serviceQueue();
-
+ serviceHttp();
+
LL_DEBUGS("LLMediaDataClient") << "QueueTimer::tick() finished, queue size is: " << mQueue.size() << LL_ENDL;
LL_DEBUGS("LLMediaDataClientQueue") << "QueueTimer::tick() finished, SORTED queue is: " << mQueue << LL_ENDL;
- return isEmpty();
+ return isDoneProcessing();
}
-LLMediaDataClient::request_ptr_t LLMediaDataClient::dequeue()
+LLMediaDataClient::Request::ptr_t LLMediaDataClient::dequeue()
{
- request_ptr_t request;
+ Request::ptr_t request;
request_queue_t *queue_p = getQueue();
if (queue_p->empty())
@@ -242,20 +272,20 @@ LLMediaDataClient::request_ptr_t LLMediaDataClient::dequeue()
else
{
// Don't return this request -- it's not ready to be serviced.
- request = NULL;
+ request.reset();
}
}
return request;
}
-void LLMediaDataClient::pushBack(request_ptr_t request)
+void LLMediaDataClient::pushBack(Request::ptr_t request)
{
request_queue_t *queue_p = getQueue();
queue_p->push_front(request);
}
-void LLMediaDataClient::trackRequest(request_ptr_t request)
+void LLMediaDataClient::trackRequest(Request::ptr_t request)
{
request_set_t::iterator iter = mUnQueuedRequests.find(request);
@@ -269,7 +299,7 @@ void LLMediaDataClient::trackRequest(request_ptr_t request)
}
}
-void LLMediaDataClient::stopTrackingRequest(request_ptr_t request)
+void LLMediaDataClient::stopTrackingRequest(Request::ptr_t request)
{
request_set_t::iterator iter = mUnQueuedRequests.find(request);
@@ -283,16 +313,22 @@ void LLMediaDataClient::stopTrackingRequest(request_ptr_t request)
}
}
+bool LLMediaDataClient::isDoneProcessing() const
+{
+ return (isEmpty() && mUnQueuedRequests.empty());
+}
+
+
void LLMediaDataClient::serviceQueue()
{
// Peel one off of the items from the queue and execute it
- request_ptr_t request;
+ Request::ptr_t request;
do
{
request = dequeue();
- if(request.isNull())
+ if(!request)
{
// Queue is empty.
return;
@@ -317,7 +353,18 @@ void LLMediaDataClient::serviceQueue()
trackRequest(request);
// and make the post
- LLHTTPClient::post(url, sd_payload, request->createResponder());
+ LLHttpSDHandler *handler = request->createHandler();
+ LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest, mHttpPolicy, 0,
+ url, sd_payload, mHttpOpts, mHttpHeaders, handler);
+
+ if (handle == LLCORE_HTTP_HANDLE_INVALID)
+ {
+ // *TODO: Change this metaphore to use boost::shared_ptr<> for handlers. Requires change in LLCore::HTTP
+ delete handler;
+ LLCore::HttpStatus status = mHttpRequest->getStatus();
+ LL_WARNS("LLMediaDataClient") << "'" << url << "' request POST failed. Reason "
+ << status.toTerseString() << " \"" << status.toString() << "\"" << LL_ENDL;
+ }
}
else
{
@@ -332,13 +379,17 @@ void LLMediaDataClient::serviceQueue()
}
else
{
- // This request has exceeded its maxumim retry count. It will be dropped.
+ // This request has exceeded its maximum retry count. It will be dropped.
LL_WARNS("LLMediaDataClient") << "Could not send request " << *request << " for " << mMaxNumRetries << " tries, dropping request." << LL_ENDL;
}
}
}
+void LLMediaDataClient::serviceHttp()
+{
+ mHttpRequest->update(0);
+}
// dump the queue
std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::request_queue_t &q)
@@ -395,7 +446,7 @@ BOOL LLMediaDataClient::QueueTimer::tick()
//
//////////////////////////////////////////////////////////////////////////////////////
-LLMediaDataClient::RetryTimer::RetryTimer(F32 time, request_ptr_t request)
+LLMediaDataClient::RetryTimer::RetryTimer(F32 time, Request::ptr_t request)
: LLEventTimer(time), mRequest(request)
{
mRequest->startTracking();
@@ -417,7 +468,7 @@ BOOL LLMediaDataClient::RetryTimer::tick()
}
// Release the ref to the request.
- mRequest = NULL;
+ mRequest.reset();
// Don't fire again
return TRUE;
@@ -490,7 +541,7 @@ void LLMediaDataClient::Request::reEnqueue()
{
if(mMDC)
{
- mMDC->enqueue(this);
+ mMDC->enqueue(shared_from_this());
}
}
@@ -533,13 +584,13 @@ bool LLMediaDataClient::Request::isDead()
void LLMediaDataClient::Request::startTracking()
{
if(mMDC)
- mMDC->trackRequest(this);
+ mMDC->trackRequest(shared_from_this());
}
void LLMediaDataClient::Request::stopTracking()
{
if(mMDC)
- mMDC->stopTrackingRequest(this);
+ mMDC->stopTrackingRequest(shared_from_this());
}
std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::Request &r)
@@ -551,79 +602,67 @@ std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::Request &r)
<< " #retries=" << r.getRetryCount();
return s;
}
-
-//////////////////////////////////////////////////////////////////////////////////////
-//
-// LLMediaDataClient::Responder
-//
-//////////////////////////////////////////////////////////////////////////////////////
-LLMediaDataClient::Responder::Responder(const request_ptr_t &request)
-: mRequest(request)
+//========================================================================
+
+LLMediaDataClient::Handler::Handler(const Request::ptr_t &request):
+ mRequest(request)
{
}
-/*virtual*/
-void LLMediaDataClient::Responder::httpFailure()
+
+void LLMediaDataClient::Handler::onSuccess(LLCore::HttpResponse * response, const LLSD &content)
{
- mRequest->stopTracking();
+ mRequest->stopTracking();
- if(mRequest->isDead())
- {
- LL_WARNS("LLMediaDataClient") << "dead request " << *mRequest << LL_ENDL;
- return;
- }
-
- if (getStatus() == HTTP_SERVICE_UNAVAILABLE)
- {
- F32 retry_timeout;
-#if 0
- // *TODO: Honor server Retry-After header.
- if (!hasResponseHeader(HTTP_IN_HEADER_RETRY_AFTER)
- || !getSecondsUntilRetryAfter(getResponseHeader(HTTP_IN_HEADER_RETRY_AFTER), retry_timeout))
-#endif
- {
- retry_timeout = mRequest->getRetryTimerDelay();
- }
-
- mRequest->incRetryCount();
-
- if (mRequest->getRetryCount() < mRequest->getMaxNumRetries())
- {
- LL_INFOS("LLMediaDataClient") << *mRequest << " got SERVICE_UNAVAILABLE...retrying in " << retry_timeout << " seconds" << LL_ENDL;
-
- // Start timer (instances are automagically tracked by
- // InstanceTracker<> and LLEventTimer)
- new RetryTimer(F32(retry_timeout/*secs*/), mRequest);
- }
- else
- {
- LL_INFOS("LLMediaDataClient") << *mRequest << " got SERVICE_UNAVAILABLE...retry count "
- << mRequest->getRetryCount() << " exceeds " << mRequest->getMaxNumRetries() << ", not retrying" << LL_ENDL;
- }
- }
- // *TODO: Redirect on 3xx status codes.
- else
- {
- LL_WARNS("LLMediaDataClient") << *mRequest << " http failure "
- << dumpResponse() << LL_ENDL;
- }
+ if (mRequest->isDead())
+ {
+ LL_WARNS("LLMediaDataClient") << "dead request " << *mRequest << LL_ENDL;
+ return;
+ }
+
+ LL_DEBUGS("LLMediaDataClientResponse") << *mRequest << LL_ENDL;
}
-/*virtual*/
-void LLMediaDataClient::Responder::httpSuccess()
+void LLMediaDataClient::Handler::onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status)
{
- mRequest->stopTracking();
+ mRequest->stopTracking();
- if(mRequest->isDead())
- {
- LL_WARNS("LLMediaDataClient") << "dead request " << *mRequest << LL_ENDL;
- return;
- }
+ if (status == LLCore::HttpStatus(HTTP_SERVICE_UNAVAILABLE))
+ {
+ F32 retry_timeout;
+#if 0
+ // *TODO: Honor server Retry-After header.
+ if (!hasResponseHeader(HTTP_IN_HEADER_RETRY_AFTER)
+ || !getSecondsUntilRetryAfter(getResponseHeader(HTTP_IN_HEADER_RETRY_AFTER), retry_timeout))
+#endif
+ {
+ retry_timeout = mRequest->getRetryTimerDelay();
+ }
+
+ mRequest->incRetryCount();
- LL_DEBUGS("LLMediaDataClientResponse") << *mRequest << " " << dumpResponse() << LL_ENDL;
+ if (mRequest->getRetryCount() < mRequest->getMaxNumRetries())
+ {
+ LL_INFOS("LLMediaDataClient") << *mRequest << " got SERVICE_UNAVAILABLE...retrying in " << retry_timeout << " seconds" << LL_ENDL;
+
+ // Start timer (instances are automagically tracked by
+ // InstanceTracker<> and LLEventTimer)
+ new RetryTimer(F32(retry_timeout/*secs*/), mRequest);
+ }
+ else
+ {
+ LL_INFOS("LLMediaDataClient") << *mRequest << " got SERVICE_UNAVAILABLE...retry count "
+ << mRequest->getRetryCount() << " exceeds " << mRequest->getMaxNumRetries() << ", not retrying" << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_WARNS("LLMediaDataClient") << *mRequest << " HTTP failure " << LL_ENDL;
+ }
}
+
//////////////////////////////////////////////////////////////////////////////////////
//
// LLObjectMediaDataClient
@@ -634,7 +673,7 @@ void LLMediaDataClient::Responder::httpSuccess()
void LLObjectMediaDataClient::fetchMedia(LLMediaDataClientObject *object)
{
// Create a get request and put it in the queue.
- enqueue(new RequestGet(object, this));
+ enqueue(Request::ptr_t(new RequestGet(object, this)));
}
const char *LLObjectMediaDataClient::getCapabilityName() const
@@ -678,14 +717,14 @@ void LLObjectMediaDataClient::sortQueue()
}
// static
-bool LLObjectMediaDataClient::compareRequestScores(const request_ptr_t &o1, const request_ptr_t &o2)
+bool LLObjectMediaDataClient::compareRequestScores(const Request::ptr_t &o1, const Request::ptr_t &o2)
{
- if (o2.isNull()) return true;
- if (o1.isNull()) return false;
+ if (!o2) return true;
+ if (!o1) return false;
return ( o1->getScore() > o2->getScore() );
}
-void LLObjectMediaDataClient::enqueue(Request *request)
+void LLObjectMediaDataClient::enqueue(Request::ptr_t request)
{
if(request->isDead())
{
@@ -703,9 +742,10 @@ void LLObjectMediaDataClient::enqueue(Request *request)
{
// For GET requests that are not new, if a matching request is already in the round robin queue,
// in flight, or being retried, leave it at its current position.
- request_queue_t::iterator iter = find_matching_request(mRoundRobinQueue, request->getID(), Request::GET);
- request_set_t::iterator iter2 = find_matching_request(mUnQueuedRequests, request->getID(), Request::GET);
-
+ PredicateMatchRequest upred(request->getID(), Request::GET);
+ request_queue_t::iterator iter = std::find_if(mRoundRobinQueue.begin(), mRoundRobinQueue.end(), upred);
+ request_set_t::iterator iter2 = std::find_if(mUnQueuedRequests.begin(), mUnQueuedRequests.end(), upred);
+
if( (iter != mRoundRobinQueue.end()) || (iter2 != mUnQueuedRequests.end()) )
{
LL_DEBUGS("LLMediaDataClient") << "ALREADY THERE: NOT Queuing request for " << *request << LL_ENDL;
@@ -718,9 +758,11 @@ void LLObjectMediaDataClient::enqueue(Request *request)
// IF the update will cause an object update message to be sent out at some point in the future, it probably should.
// Remove any existing requests of this type for this object
- remove_matching_requests(mQueue, request->getID(), request->getType());
- remove_matching_requests(mRoundRobinQueue, request->getID(), request->getType());
- remove_matching_requests(mUnQueuedRequests, request->getID(), request->getType());
+ PredicateMatchRequest upred(request->getID(), request->getType());
+
+ mark_dead_and_remove_if(mQueue, upred);
+ mark_dead_and_remove_if(mRoundRobinQueue, upred);
+ mark_dead_and_remove_if(mUnQueuedRequests, upred);
if (is_new)
{
@@ -749,7 +791,7 @@ void LLObjectMediaDataClient::enqueue(Request *request)
startQueueTimer();
}
-bool LLObjectMediaDataClient::canServiceRequest(request_ptr_t request)
+bool LLObjectMediaDataClient::canServiceRequest(Request::ptr_t request)
{
if(mCurrentQueueIsTheSortedQueue)
{
@@ -785,9 +827,9 @@ bool LLObjectMediaDataClient::isInQueue(const LLMediaDataClientObject::ptr_t &ob
if(LLMediaDataClient::isInQueue(object))
return true;
- if(find_matching_request(mRoundRobinQueue, object->getID(), LLMediaDataClient::Request::ANY) != mRoundRobinQueue.end())
- return true;
-
+ if (std::find_if(mRoundRobinQueue.begin(), mRoundRobinQueue.end(), PredicateMatchRequest(object->getID())) != mRoundRobinQueue.end())
+ return true;
+
return false;
}
@@ -796,12 +838,12 @@ void LLObjectMediaDataClient::removeFromQueue(const LLMediaDataClientObject::ptr
// First, call parent impl.
LLMediaDataClient::removeFromQueue(object);
- remove_matching_requests(mRoundRobinQueue, object->getID(), LLMediaDataClient::Request::ANY);
+ mark_dead_and_remove_if(mRoundRobinQueue, PredicateMatchRequest(object->getID()));
}
bool LLObjectMediaDataClient::processQueueTimer()
{
- if(isEmpty())
+ if (isDoneProcessing())
return true;
LL_DEBUGS("LLMediaDataClient") << "started, SORTED queue size is: " << mQueue.size()
@@ -816,6 +858,7 @@ bool LLObjectMediaDataClient::processQueueTimer()
LL_DEBUGS("LLMediaDataClientQueue") << "after sort, SORTED queue is: " << mQueue << LL_ENDL;
serviceQueue();
+ serviceHttp();
swapCurrentQueue();
@@ -824,7 +867,7 @@ bool LLObjectMediaDataClient::processQueueTimer()
LL_DEBUGS("LLMediaDataClientQueue") << " SORTED queue is: " << mQueue << LL_ENDL;
LL_DEBUGS("LLMediaDataClientQueue") << " RR queue is: " << mRoundRobinQueue << LL_ENDL;
- return isEmpty();
+ return isDoneProcessing();
}
LLObjectMediaDataClient::RequestGet::RequestGet(LLMediaDataClientObject *obj, LLMediaDataClient *mdc):
@@ -841,16 +884,16 @@ LLSD LLObjectMediaDataClient::RequestGet::getPayload() const
return result;
}
-LLMediaDataClient::Responder *LLObjectMediaDataClient::RequestGet::createResponder()
+LLHttpSDHandler *LLObjectMediaDataClient::RequestGet::createHandler()
{
- return new LLObjectMediaDataClient::Responder(this);
+ return new LLObjectMediaDataClient::Handler(shared_from_this());
}
void LLObjectMediaDataClient::updateMedia(LLMediaDataClientObject *object)
{
// Create an update request and put it in the queue.
- enqueue(new RequestUpdate(object, this));
+ enqueue(Request::ptr_t(new RequestUpdate(object, this)));
}
LLObjectMediaDataClient::RequestUpdate::RequestUpdate(LLMediaDataClientObject *obj, LLMediaDataClient *mdc):
@@ -877,60 +920,58 @@ LLSD LLObjectMediaDataClient::RequestUpdate::getPayload() const
return result;
}
-LLMediaDataClient::Responder *LLObjectMediaDataClient::RequestUpdate::createResponder()
+LLHttpSDHandler *LLObjectMediaDataClient::RequestUpdate::createHandler()
{
// This just uses the base class's responder.
- return new LLMediaDataClient::Responder(this);
+ return new LLMediaDataClient::Handler(shared_from_this());
}
-
-/*virtual*/
-void LLObjectMediaDataClient::Responder::httpSuccess()
+void LLObjectMediaDataClient::Handler::onSuccess(LLCore::HttpResponse * response, const LLSD &content)
{
- getRequest()->stopTracking();
-
- if(getRequest()->isDead())
- {
- LL_WARNS("LLMediaDataClient") << "dead request " << *(getRequest()) << LL_ENDL;
- return;
- }
-
- const LLSD& content = getContent();
- if (!content.isMap())
- {
- failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
- return;
- }
+ LLMediaDataClient::Handler::onSuccess(response, content);
+
+ if (getRequest()->isDead())
+ { // warning emitted from base method.
+ return;
+ }
+
+ if (!content.isMap())
+ {
+ onFailure(response, LLCore::HttpStatus(HTTP_INTERNAL_ERROR, "Malformed response contents"));
+ return;
+ }
+
+ // This responder is only used for GET requests, not UPDATE.
+ LL_DEBUGS("LLMediaDataClientResponse") << *(getRequest()) << " " << LL_ENDL;
+
+ // Look for an error
+ if (content.has("error"))
+ {
+ const LLSD &error = content["error"];
+ LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error getting media data for object: code=" <<
+ error["code"].asString() << ": " << error["message"].asString() << LL_ENDL;
+
+ // XXX Warn user?
+ }
+ else
+ {
+ // Check the data
+ const LLUUID &object_id = content[LLTextureEntry::OBJECT_ID_KEY];
+ if (object_id != getRequest()->getObject()->getID())
+ {
+ // NOT good, wrong object id!!
+ LL_WARNS("LLMediaDataClient") << *(getRequest()) << " DROPPING response with wrong object id (" << object_id << ")" << LL_ENDL;
+ return;
+ }
+
+ // Otherwise, update with object media data
+ getRequest()->getObject()->updateObjectMediaData(content[LLTextureEntry::OBJECT_MEDIA_DATA_KEY],
+ content[LLTextureEntry::MEDIA_VERSION_KEY]);
+ }
- // This responder is only used for GET requests, not UPDATE.
- LL_DEBUGS("LLMediaDataClientResponse") << *(getRequest()) << " " << dumpResponse() << LL_ENDL;
-
- // Look for an error
- if (content.has("error"))
- {
- const LLSD &error = content["error"];
- LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error getting media data for object: code=" <<
- error["code"].asString() << ": " << error["message"].asString() << LL_ENDL;
-
- // XXX Warn user?
- }
- else
- {
- // Check the data
- const LLUUID &object_id = content[LLTextureEntry::OBJECT_ID_KEY];
- if (object_id != getRequest()->getObject()->getID())
- {
- // NOT good, wrong object id!!
- LL_WARNS("LLMediaDataClient") << *(getRequest()) << " DROPPING response with wrong object id (" << object_id << ")" << LL_ENDL;
- return;
- }
-
- // Otherwise, update with object media data
- getRequest()->getObject()->updateObjectMediaData(content[LLTextureEntry::OBJECT_MEDIA_DATA_KEY],
- content[LLTextureEntry::MEDIA_VERSION_KEY]);
- }
}
+
//////////////////////////////////////////////////////////////////////////////////////
//
// LLObjectMediaNavigateClient
@@ -943,16 +984,18 @@ const char *LLObjectMediaNavigateClient::getCapabilityName() const
return "ObjectMediaNavigate";
}
-void LLObjectMediaNavigateClient::enqueue(Request *request)
+void LLObjectMediaNavigateClient::enqueue(Request::ptr_t request)
{
if(request->isDead())
{
- LL_DEBUGS("LLMediaDataClient") << "not queueing dead request " << *request << LL_ENDL;
+ LL_DEBUGS("LLMediaDataClient") << "not queuing dead request " << *request << LL_ENDL;
return;
}
+ PredicateMatchRequest upred(request);
+
// If there's already a matching request in the queue, remove it.
- request_queue_t::iterator iter = find_matching_request(mQueue, request, LLMediaDataClient::Request::ANY);
+ request_queue_t::iterator iter = std::find_if(mQueue.begin(), mQueue.end(), upred);
if(iter != mQueue.end())
{
LL_DEBUGS("LLMediaDataClient") << "removing matching queued request " << (**iter) << LL_ENDL;
@@ -960,7 +1003,7 @@ void LLObjectMediaNavigateClient::enqueue(Request *request)
}
else
{
- request_set_t::iterator set_iter = find_matching_request(mUnQueuedRequests, request, LLMediaDataClient::Request::ANY);
+ request_set_t::iterator set_iter = std::find_if(mUnQueuedRequests.begin(), mUnQueuedRequests.end(), upred);
if(set_iter != mUnQueuedRequests.end())
{
LL_DEBUGS("LLMediaDataClient") << "removing matching unqueued request " << (**set_iter) << LL_ENDL;
@@ -979,7 +1022,7 @@ void LLObjectMediaNavigateClient::enqueue(Request *request)
else
#endif
{
- LL_DEBUGS("LLMediaDataClient") << "queueing new request " << (*request) << LL_ENDL;
+ LL_DEBUGS("LLMediaDataClient") << "queuing new request " << (*request) << LL_ENDL;
mQueue.push_back(request);
// Start the timer if not already running
@@ -993,7 +1036,7 @@ void LLObjectMediaNavigateClient::navigate(LLMediaDataClientObject *object, U8 t
// LL_INFOS("LLMediaDataClient") << "navigate() initiated: " << ll_print_sd(sd_payload) << LL_ENDL;
// Create a get request and put it in the queue.
- enqueue(new RequestNavigate(object, this, texture_index, url));
+ enqueue(Request::ptr_t(new RequestNavigate(object, this, texture_index, url)));
}
LLObjectMediaNavigateClient::RequestNavigate::RequestNavigate(LLMediaDataClientObject *obj, LLMediaDataClient *mdc, U8 texture_index, const std::string &url):
@@ -1012,75 +1055,67 @@ LLSD LLObjectMediaNavigateClient::RequestNavigate::getPayload() const
return result;
}
-LLMediaDataClient::Responder *LLObjectMediaNavigateClient::RequestNavigate::createResponder()
+LLHttpSDHandler *LLObjectMediaNavigateClient::RequestNavigate::createHandler()
{
- return new LLObjectMediaNavigateClient::Responder(this);
+ return new LLObjectMediaNavigateClient::Handler(shared_from_this());
}
-/*virtual*/
-void LLObjectMediaNavigateClient::Responder::httpFailure()
+void LLObjectMediaNavigateClient::Handler::onSuccess(LLCore::HttpResponse * response, const LLSD &content)
{
- getRequest()->stopTracking();
+ LLMediaDataClient::Handler::onSuccess(response, content);
- if(getRequest()->isDead())
- {
- LL_WARNS("LLMediaDataClient") << "dead request " << *(getRequest()) << LL_ENDL;
- return;
- }
+ if (getRequest()->isDead())
+ { // already warned.
+ return;
+ }
+
+ LL_INFOS("LLMediaDataClient") << *(getRequest()) << " NAVIGATE returned" << LL_ENDL;
+
+ if (content.has("error"))
+ {
+ const LLSD &error = content["error"];
+ int error_code = error["code"];
+
+ if (ERROR_PERMISSION_DENIED_CODE == error_code)
+ {
+ mediaNavigateBounceBack();
+ }
+ else
+ {
+ LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error navigating: code=" <<
+ error["code"].asString() << ": " << error["message"].asString() << LL_ENDL;
+ }
+
+ // XXX Warn user?
+ }
+ else
+ {
+ // No action required.
+ LL_DEBUGS("LLMediaDataClientResponse") << *(getRequest()) << LL_ENDL;
+ }
- // Bounce back (unless HTTP_SERVICE_UNAVAILABLE, in which case call base
- // class
- if (getStatus() == HTTP_SERVICE_UNAVAILABLE)
- {
- LLMediaDataClient::Responder::httpFailure();
- }
- else
- {
- // bounce the face back
- 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]);
- }
}
-/*virtual*/
-void LLObjectMediaNavigateClient::Responder::httpSuccess()
+void LLObjectMediaNavigateClient::Handler::onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status)
{
- getRequest()->stopTracking();
+ LLMediaDataClient::Handler::onFailure(response, status);
- if(getRequest()->isDead())
- {
- LL_WARNS("LLMediaDataClient") << "dead request " << *(getRequest()) << LL_ENDL;
- return;
- }
+ if (getRequest()->isDead())
+ { // already warned.
+ return;
+ }
- LL_INFOS("LLMediaDataClient") << *(getRequest()) << " NAVIGATE returned " << dumpResponse() << LL_ENDL;
-
- const LLSD& content = getContent();
- if (content.has("error"))
- {
- const LLSD &error = content["error"];
- int error_code = error["code"];
-
- if (ERROR_PERMISSION_DENIED_CODE == error_code)
- {
- LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Navigation denied: bounce back" << LL_ENDL;
- const LLSD &payload = getRequest()->getPayload();
- // bounce the face back
- getRequest()->getObject()->mediaNavigateBounceBack((LLSD::Integer)payload[LLTextureEntry::TEXTURE_INDEX_KEY]);
- }
- else
- {
- LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error navigating: code=" <<
- error["code"].asString() << ": " << error["message"].asString() << LL_ENDL;
- }
+ if (status != LLCore::HttpStatus(HTTP_SERVICE_UNAVAILABLE))
+ {
+ mediaNavigateBounceBack();
+ }
+}
- // XXX Warn user?
- }
- else
- {
- // No action required.
- LL_DEBUGS("LLMediaDataClientResponse") << *(getRequest()) << " " << dumpResponse() << LL_ENDL;
- }
+void LLObjectMediaNavigateClient::Handler::mediaNavigateBounceBack()
+{
+ LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error navigating or denied." << LL_ENDL;
+ const LLSD &payload = getRequest()->getPayload();
+
+ // bounce the face back
+ getRequest()->getObject()->mediaNavigateBounceBack((LLSD::Integer)payload[LLTextureEntry::TEXTURE_INDEX_KEY]);
}
diff --git a/indra/newview/llmediadataclient.h b/indra/newview/llmediadataclient.h
index 80dd519812..9907897613 100755
--- a/indra/newview/llmediadataclient.h
+++ b/indra/newview/llmediadataclient.h
@@ -27,12 +27,15 @@
#ifndef LL_LLMEDIADATACLIENT_H
#define LL_LLMEDIADATACLIENT_H
-#include "llhttpclient.h"
#include <set>
#include "llrefcount.h"
#include "llpointer.h"
#include "lleventtimer.h"
-
+#include "llhttpsdhandler.h"
+#include "httpcommon.h"
+#include "httprequest.h"
+#include "httpoptions.h"
+#include "httpheaders.h"
// Link seam for LLVOVolume
class LLMediaDataClientObject : public LLRefCount
@@ -74,6 +77,8 @@ public:
// Abstracts the Cap URL, the request, and the responder
class LLMediaDataClient : public LLRefCount
{
+ friend class PredicateMatchRequest;
+
protected:
LOG_CLASS(LLMediaDataClient);
public:
@@ -109,26 +114,30 @@ protected:
// Destructor
virtual ~LLMediaDataClient(); // use unref
- class Responder;
-
// Request (pure virtual base class for requests in the queue)
- class Request : public LLRefCount
- {
- public:
- // Subclasses must implement this to build a payload for their request type.
- virtual LLSD getPayload() const = 0;
- // and must create the correct type of responder.
- virtual Responder *createResponder() = 0;
+ class Request:
+ public boost::enable_shared_from_this<Request>
+ {
+ public:
+ typedef boost::shared_ptr<Request> ptr_t;
- virtual std::string getURL() { return ""; }
+ // Subclasses must implement this to build a payload for their request type.
+ virtual LLSD getPayload() const = 0;
+ // and must create the correct type of responder.
+ virtual LLHttpSDHandler *createHandler() = 0;
+
+ virtual std::string getURL() { return ""; }
enum Type {
GET,
UPDATE,
NAVIGATE,
- ANY
+ ANY
};
-
+
+ virtual ~Request()
+ { }
+
protected:
// The only way to create one of these is through a subclass.
Request(Type in_type, LLMediaDataClientObject *obj, LLMediaDataClient *mdc, S32 face = -1);
@@ -166,7 +175,7 @@ protected:
const LLUUID &getID() const { return mObjectID; }
S32 getFace() const { return mFace; }
- bool isMatch (const Request* other, Type match_type = ANY) const
+ bool isMatch (const Request::ptr_t &other, Type match_type = ANY) const
{
return ((match_type == ANY) || (mType == other->mType)) &&
(mFace == other->mFace) &&
@@ -188,61 +197,62 @@ protected:
// Back pointer to the MDC...not a ref!
LLMediaDataClient *mMDC;
};
- typedef LLPointer<Request> request_ptr_t;
+ //typedef LLPointer<Request> request_ptr_t;
- // Responder
- class Responder : public LLHTTPClient::Responder
- {
- LOG_CLASS(Responder);
- public:
- Responder(const request_ptr_t &request);
- request_ptr_t &getRequest() { return mRequest; }
+ class Handler : public LLHttpSDHandler
+ {
+ LOG_CLASS(Handler);
+ public:
+ Handler(const Request::ptr_t &request);
+ Request::ptr_t getRequest() const { return mRequest; }
- protected:
- //If we get back an error (not found, etc...), handle it here
- virtual void httpFailure();
- //If we get back a normal response, handle it here. Default just logs it.
- virtual void httpSuccess();
+ protected:
+ virtual void onSuccess(LLCore::HttpResponse * response, const LLSD &content);
+ virtual void onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status);
+
+ private:
+ Request::ptr_t mRequest;
+ };
- private:
- request_ptr_t mRequest;
- };
class RetryTimer : public LLEventTimer
{
public:
- RetryTimer(F32 time, request_ptr_t);
+ RetryTimer(F32 time, Request::ptr_t);
virtual BOOL tick();
private:
// back-pointer
- request_ptr_t mRequest;
+ Request::ptr_t mRequest;
};
protected:
- typedef std::list<request_ptr_t> request_queue_t;
- typedef std::set<request_ptr_t> request_set_t;
+ typedef std::list<Request::ptr_t> request_queue_t;
+ typedef std::set<Request::ptr_t> request_set_t;
// Subclasses must override to return a cap name
virtual const char *getCapabilityName() const = 0;
// Puts the request into a queue, appropriately handling duplicates, etc.
- virtual void enqueue(Request*) = 0;
+ virtual void enqueue(Request::ptr_t) = 0;
virtual void serviceQueue();
+ virtual void serviceHttp();
virtual request_queue_t *getQueue() { return &mQueue; };
// Gets the next request, removing it from the queue
- virtual request_ptr_t dequeue();
+ virtual Request::ptr_t dequeue();
- virtual bool canServiceRequest(request_ptr_t request) { return true; };
+ virtual bool canServiceRequest(Request::ptr_t request) { return true; };
// Returns a request to the head of the queue (should only be used for requests that came from dequeue
- virtual void pushBack(request_ptr_t request);
+ virtual void pushBack(Request::ptr_t request);
- void trackRequest(request_ptr_t request);
- void stopTrackingRequest(request_ptr_t request);
+ void trackRequest(Request::ptr_t request);
+ void stopTrackingRequest(Request::ptr_t request);
+
+ bool isDoneProcessing() const;
request_queue_t mQueue;
@@ -260,6 +270,11 @@ protected:
void startQueueTimer();
void stopQueueTimer();
+ LLCore::HttpRequest::ptr_t mHttpRequest;
+ LLCore::HttpHeaders::ptr_t mHttpHeaders;
+ LLCore::HttpOptions::ptr_t mHttpOpts;
+ LLCore::HttpRequest::policy_t mHttpPolicy;
+
private:
static F64 getObjectScore(const LLMediaDataClientObject::ptr_t &obj);
@@ -281,9 +296,9 @@ private:
bool mQueueTimerIsRunning;
- template <typename T> friend typename T::iterator find_matching_request(T &c, const LLMediaDataClient::Request *request, LLMediaDataClient::Request::Type match_type);
- template <typename T> friend typename T::iterator find_matching_request(T &c, const LLUUID &id, LLMediaDataClient::Request::Type match_type);
- template <typename T> friend void remove_matching_requests(T &c, const LLUUID &id, LLMediaDataClient::Request::Type match_type);
+// template <typename T> friend typename T::iterator find_matching_request(T &c, const LLMediaDataClient::Request *request, LLMediaDataClient::Request::Type match_type);
+// template <typename T> friend typename T::iterator find_matching_request(T &c, const LLUUID &id, LLMediaDataClient::Request::Type match_type);
+// template <typename T> friend void remove_matching_requests(T &c, const LLUUID &id, LLMediaDataClient::Request::Type match_type);
};
// MediaDataClient specific for the ObjectMedia cap
@@ -309,7 +324,7 @@ public:
public:
RequestGet(LLMediaDataClientObject *obj, LLMediaDataClient *mdc);
/*virtual*/ LLSD getPayload() const;
- /*virtual*/ Responder *createResponder();
+ /*virtual*/ LLHttpSDHandler *createHandler();
};
class RequestUpdate: public Request
@@ -317,7 +332,7 @@ public:
public:
RequestUpdate(LLMediaDataClientObject *obj, LLMediaDataClient *mdc);
/*virtual*/ LLSD getPayload() const;
- /*virtual*/ Responder *createResponder();
+ /*virtual*/ LLHttpSDHandler *createHandler();
};
// Returns true iff the queue is empty
@@ -331,7 +346,7 @@ public:
virtual bool processQueueTimer();
- virtual bool canServiceRequest(request_ptr_t request);
+ virtual bool canServiceRequest(Request::ptr_t request);
protected:
// Subclasses must override to return a cap name
@@ -340,17 +355,20 @@ protected:
virtual request_queue_t *getQueue();
// Puts the request into the appropriate queue
- virtual void enqueue(Request*);
+ virtual void enqueue(Request::ptr_t);
- class Responder : public LLMediaDataClient::Responder
+ class Handler: public LLMediaDataClient::Handler
{
- LOG_CLASS(Responder);
+ LOG_CLASS(Handler);
public:
- Responder(const request_ptr_t &request)
- : LLMediaDataClient::Responder(request) {}
+ Handler(const Request::ptr_t &request):
+ LLMediaDataClient::Handler(request)
+ {}
+
protected:
- virtual void httpSuccess();
+ virtual void onSuccess(LLCore::HttpResponse * response, const LLSD &content);
};
+
private:
// The Get/Update data client needs a second queue to avoid object updates starving load-ins.
void swapCurrentQueue();
@@ -359,7 +377,7 @@ private:
bool mCurrentQueueIsTheSortedQueue;
// Comparator for sorting
- static bool compareRequestScores(const request_ptr_t &o1, const request_ptr_t &o2);
+ static bool compareRequestScores(const Request::ptr_t &o1, const Request::ptr_t &o2);
void sortQueue();
};
@@ -384,14 +402,14 @@ public:
void navigate(LLMediaDataClientObject *object, U8 texture_index, const std::string &url);
// Puts the request into the appropriate queue
- virtual void enqueue(Request*);
+ virtual void enqueue(Request::ptr_t);
class RequestNavigate: public Request
{
public:
RequestNavigate(LLMediaDataClientObject *obj, LLMediaDataClient *mdc, U8 texture_index, const std::string &url);
/*virtual*/ LLSD getPayload() const;
- /*virtual*/ Responder *createResponder();
+ /*virtual*/ LLHttpSDHandler *createHandler();
/*virtual*/ std::string getURL() { return mURL; }
private:
std::string mURL;
@@ -401,15 +419,18 @@ protected:
// Subclasses must override to return a cap name
virtual const char *getCapabilityName() const;
- class Responder : public LLMediaDataClient::Responder
+ class Handler : public LLMediaDataClient::Handler
{
- LOG_CLASS(Responder);
+ LOG_CLASS(Handler);
public:
- Responder(const request_ptr_t &request)
- : LLMediaDataClient::Responder(request) {}
+ Handler(const Request::ptr_t &request):
+ LLMediaDataClient::Handler(request)
+ {}
+
protected:
- virtual void httpFailure();
- virtual void httpSuccess();
+ virtual void onSuccess(LLCore::HttpResponse * response, const LLSD &content);
+ virtual void onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status);
+
private:
void mediaNavigateBounceBack();
};
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 648056484e..d6aaf18cb7 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -738,9 +738,9 @@ void log_upload_error(LLCore::HttpStatus status, const LLSD& content,
LLMeshRepoThread::LLMeshRepoThread()
: LLThread("mesh repo"),
mHttpRequest(NULL),
- mHttpOptions(NULL),
- mHttpLargeOptions(NULL),
- mHttpHeaders(NULL),
+ mHttpOptions(),
+ mHttpLargeOptions(),
+ mHttpHeaders(),
mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
mHttpLegacyPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
mHttpLargePolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
@@ -753,13 +753,13 @@ LLMeshRepoThread::LLMeshRepoThread()
mHeaderMutex = new LLMutex(NULL);
mSignal = new LLCondition(NULL);
mHttpRequest = new LLCore::HttpRequest;
- mHttpOptions = new LLCore::HttpOptions;
+ mHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
mHttpOptions->setTransferTimeout(SMALL_MESH_XFER_TIMEOUT);
mHttpOptions->setUseRetryAfter(gSavedSettings.getBOOL("MeshUseHttpRetryAfter"));
- mHttpLargeOptions = new LLCore::HttpOptions;
+ mHttpLargeOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
mHttpLargeOptions->setTransferTimeout(LARGE_MESH_XFER_TIMEOUT);
mHttpLargeOptions->setUseRetryAfter(gSavedSettings.getBOOL("MeshUseHttpRetryAfter"));
- mHttpHeaders = new LLCore::HttpHeaders;
+ mHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders);
mHttpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_VND_LL_MESH);
mHttpPolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_MESH2);
mHttpLegacyPolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_MESH1);
@@ -781,22 +781,9 @@ LLMeshRepoThread::~LLMeshRepoThread()
delete *iter;
}
mHttpRequestSet.clear();
- if (mHttpHeaders)
- {
- mHttpHeaders->release();
- mHttpHeaders = NULL;
- }
- if (mHttpOptions)
- {
- mHttpOptions->release();
- mHttpOptions = NULL;
- }
- if (mHttpLargeOptions)
- {
- mHttpLargeOptions->release();
- mHttpLargeOptions = NULL;
- }
- delete mHttpRequest;
+ mHttpHeaders.reset();
+
+ delete mHttpRequest;
mHttpRequest = NULL;
delete mMutex;
mMutex = NULL;
@@ -1882,11 +1869,11 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data,
mMeshUploadTimeOut = gSavedSettings.getS32("MeshUploadTimeOut") ;
mHttpRequest = new LLCore::HttpRequest;
- mHttpOptions = new LLCore::HttpOptions;
+ mHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
mHttpOptions->setTransferTimeout(mMeshUploadTimeOut);
mHttpOptions->setUseRetryAfter(gSavedSettings.getBOOL("MeshUseHttpRetryAfter"));
mHttpOptions->setRetries(UPLOAD_RETRY_LIMIT);
- mHttpHeaders = new LLCore::HttpHeaders;
+ mHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders);
mHttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML);
mHttpPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicy(LLAppCoreHttp::AP_UPLOADS);
mHttpPriority = 0;
@@ -1894,16 +1881,6 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data,
LLMeshUploadThread::~LLMeshUploadThread()
{
- if (mHttpHeaders)
- {
- mHttpHeaders->release();
- mHttpHeaders = NULL;
- }
- if (mHttpOptions)
- {
- mHttpOptions->release();
- mHttpOptions = NULL;
- }
delete mHttpRequest;
mHttpRequest = NULL;
}
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 39280bea3a..55157cc040 100755
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -322,9 +322,9 @@ public:
// llcorehttp library interface objects.
LLCore::HttpStatus mHttpStatus;
LLCore::HttpRequest * mHttpRequest;
- LLCore::HttpOptions * mHttpOptions;
- LLCore::HttpOptions * mHttpLargeOptions;
- LLCore::HttpHeaders * mHttpHeaders;
+ LLCore::HttpOptions::ptr_t mHttpOptions;
+ LLCore::HttpOptions::ptr_t mHttpLargeOptions;
+ LLCore::HttpHeaders::ptr_t mHttpHeaders;
LLCore::HttpRequest::policy_t mHttpPolicyClass;
LLCore::HttpRequest::policy_t mHttpLegacyPolicyClass;
LLCore::HttpRequest::policy_t mHttpLargePolicyClass;
@@ -493,8 +493,8 @@ private:
// llcorehttp library interface objects.
LLCore::HttpStatus mHttpStatus;
LLCore::HttpRequest * mHttpRequest;
- LLCore::HttpOptions * mHttpOptions;
- LLCore::HttpHeaders * mHttpHeaders;
+ LLCore::HttpOptions::ptr_t mHttpOptions;
+ LLCore::HttpHeaders::ptr_t mHttpHeaders;
LLCore::HttpRequest::policy_t mHttpPolicyClass;
LLCore::HttpRequest::priority_t mHttpPriority;
};
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index 878f1af9ef..5d1ae4ff10 100755
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -34,14 +34,12 @@
#include "lldispatcher.h"
#include "llfloaterreg.h"
-#include "llhttpclient.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
#include "llparcel.h"
#include "llagent.h"
#include "llclassifiedflags.h"
-#include "llclassifiedstatsresponder.h"
#include "llcommandhandler.h" // for classified HTML detail page click tracking
#include "lliconctrl.h"
#include "lllineeditor.h"
@@ -57,6 +55,7 @@
#include "llscrollcontainer.h"
#include "llstatusbar.h"
#include "llviewertexture.h"
+#include "llcorehttputil.h"
const S32 MINIMUM_PRICE_FOR_LISTING = 50; // L$
@@ -91,19 +90,6 @@ public:
};
static LLDispatchClassifiedClickThrough sClassifiedClickThrough;
-// Just to debug errors. Can be thrown away later.
-class LLClassifiedClickMessageResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(LLClassifiedClickMessageResponder);
-
-protected:
- // If we get back an error (not found, etc...), handle it here
- virtual void httpFailure()
- {
- LL_WARNS() << "Sending click message failed " << dumpResponse() << LL_ENDL;
- }
-};
-
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
@@ -229,8 +215,10 @@ void LLPanelClassifiedInfo::onOpen(const LLSD& key)
{
LL_INFOS() << "Classified stat request via capability" << LL_ENDL;
LLSD body;
- body["classified_id"] = getClassifiedId();
- LLHTTPClient::post(url, body, new LLClassifiedStatsResponder(getClassifiedId()));
+ LLUUID classifiedId = getClassifiedId();
+ body["classified_id"] = classifiedId;
+ LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(url, body,
+ boost::bind(&LLPanelClassifiedInfo::handleSearchStatResponse, classifiedId, _1));
}
// Update classified click stats.
@@ -240,6 +228,23 @@ void LLPanelClassifiedInfo::onOpen(const LLSD& key)
setInfoLoaded(false);
}
+/*static*/
+void LLPanelClassifiedInfo::handleSearchStatResponse(LLUUID classifiedId, LLSD result)
+{
+ S32 teleport = result["teleport_clicks"].asInteger();
+ S32 map = result["map_clicks"].asInteger();
+ S32 profile = result["profile_clicks"].asInteger();
+ S32 search_teleport = result["search_teleport_clicks"].asInteger();
+ S32 search_map = result["search_map_clicks"].asInteger();
+ S32 search_profile = result["search_profile_clicks"].asInteger();
+
+ LLPanelClassifiedInfo::setClickThrough(classifiedId,
+ teleport + search_teleport,
+ map + search_map,
+ profile + search_profile,
+ true);
+}
+
void LLPanelClassifiedInfo::processProperties(void* data, EAvatarProcessorType type)
{
if(APT_CLASSIFIED_INFO == type)
@@ -548,7 +553,8 @@ void LLPanelClassifiedInfo::sendClickMessage(
std::string url = gAgent.getRegion()->getCapability("SearchStatTracking");
LL_INFOS() << "Sending click msg via capability (url=" << url << ")" << LL_ENDL;
LL_INFOS() << "body: [" << body << "]" << LL_ENDL;
- LLHTTPClient::post(url, body, new LLClassifiedClickMessageResponder());
+ LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, body,
+ "SearchStatTracking Click report sent.", "SearchStatTracking Click report NOT sent.");
}
void LLPanelClassifiedInfo::sendClickMessage(const std::string& type)
diff --git a/indra/newview/llpanelclassified.h b/indra/newview/llpanelclassified.h
index cedd65c405..b292782615 100755
--- a/indra/newview/llpanelclassified.h
+++ b/indra/newview/llpanelclassified.h
@@ -37,6 +37,8 @@
#include "llrect.h"
#include "lluuid.h"
#include "v3dmath.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
class LLScrollContainer;
class LLTextureCtrl;
@@ -193,6 +195,9 @@ private:
S32 mMapClicksNew;
S32 mProfileClicksNew;
+ static void handleSearchStatResponse(LLUUID classifiedId, LLSD result);
+
+
typedef std::list<LLPanelClassifiedInfo*> panel_list_t;
static panel_list_t sAllPanels;
};
diff --git a/indra/newview/llpanelexperiencepicker.cpp b/indra/newview/llpanelexperiencepicker.cpp
index 70d826a407..c7a353a6af 100644
--- a/indra/newview/llpanelexperiencepicker.cpp
+++ b/indra/newview/llpanelexperiencepicker.cpp
@@ -42,6 +42,7 @@
#include "llviewercontrol.h"
#include "llfloater.h"
#include "lltrans.h"
+#include "llhttpclient.h" // *TODO: Rider, remove when converting
#define BTN_FIND "find"
#define BTN_OK "ok_btn"
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index 1d73d4bd6e..cd1dc0f070 100755
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -1352,17 +1352,8 @@ void LLLandmarksPanel::doCreatePick(LLLandmark* landmark)
std::string url = region->getCapability("RemoteParcelRequest");
if (!url.empty())
{
- body["location"] = ll_sd_from_vector3(region_pos);
- if (!region_id.isNull())
- {
- body["region_id"] = region_id;
- }
- if (!pos_global.isExactlyZero())
- {
- U64 region_handle = to_region_handle(pos_global);
- body["region_handle"] = ll_sd_from_U64(region_handle);
- }
- LLHTTPClient::post(url, body, new LLRemoteParcelRequestResponder(getObserverHandle()));
+ LLRemoteParcelInfoProcessor::getInstance()->requestRegionParcelInfo(url,
+ region_id, region_pos, pos_global, getObserverHandle());
}
else
{
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index cc8c3edd51..99c9fad82d 100755
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -59,7 +59,6 @@
#include "llviewernetwork.h"
#include "llviewerwindow.h" // to link into child list
#include "lluictrlfactory.h"
-#include "llhttpclient.h"
#include "llweb.h"
#include "llmediactrl.h"
#include "llrootview.h"
diff --git a/indra/newview/llpanelme.cpp b/indra/newview/llpanelme.cpp
index cedd3025fc..55e4ffff5e 100755
--- a/indra/newview/llpanelme.cpp
+++ b/indra/newview/llpanelme.cpp
@@ -37,7 +37,6 @@
#include "llfloaterreg.h"
#include "llhints.h"
#include "llviewercontrol.h"
-#include "llviewerdisplayname.h"
// Linden libraries
#include "llavatarnamecache.h" // IDEVO
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index e62b5a4f1d..cec56a7ae7 100755
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -45,6 +45,7 @@
#include "llpanelpick.h"
#include "lltexturectrl.h"
#include "llviewerregion.h"
+#include "llhttpconstants.h"
LLPanelPlaceInfo::LLPanelPlaceInfo()
: LLPanel(),
@@ -150,17 +151,8 @@ void LLPanelPlaceInfo::displayParcelInfo(const LLUUID& region_id,
std::string url = region->getCapability("RemoteParcelRequest");
if (!url.empty())
{
- body["location"] = ll_sd_from_vector3(mPosRegion);
- if (!region_id.isNull())
- {
- body["region_id"] = region_id;
- }
- if (!pos_global.isExactlyZero())
- {
- U64 region_handle = to_region_handle(pos_global);
- body["region_handle"] = ll_sd_from_U64(region_handle);
- }
- LLHTTPClient::post(url, body, new LLRemoteParcelRequestResponder(getObserverHandle()));
+ LLRemoteParcelInfoProcessor::getInstance()->requestRegionParcelInfo(url,
+ region_id, mPosRegion, pos_global, getObserverHandle());
}
else
{
diff --git a/indra/newview/llpathfindingmanager.cpp b/indra/newview/llpathfindingmanager.cpp
index 4977a72dc6..2e6937a79f 100755
--- a/indra/newview/llpathfindingmanager.cpp
+++ b/indra/newview/llpathfindingmanager.cpp
@@ -39,7 +39,6 @@
#include <boost/signals2.hpp>
#include "llagent.h"
-#include "llhttpclient.h"
#include "llhttpnode.h"
#include "llnotificationsutil.h"
#include "llpathfindingcharacterlist.h"
@@ -55,6 +54,8 @@
#include "lluuid.h"
#include "llviewerregion.h"
#include "llweb.h"
+#include "llcorehttputil.h"
+#include "llworld.h"
#define CAP_SERVICE_RETRIEVE_NAVMESH "RetrieveNavMeshSrc"
@@ -98,82 +99,6 @@ public:
LLHTTPRegistration<LLAgentStateChangeNode> gHTTPRegistrationAgentStateChangeNode(SIM_MESSAGE_AGENT_STATE_UPDATE);
//---------------------------------------------------------------------------
-// NavMeshStatusResponder
-//---------------------------------------------------------------------------
-
-class NavMeshStatusResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(NavMeshStatusResponder);
-public:
- NavMeshStatusResponder(LLViewerRegion *pRegion, bool pIsGetStatusOnly);
- virtual ~NavMeshStatusResponder();
-
-protected:
- virtual void httpSuccess();
- virtual void httpFailure();
-
-private:
- LLViewerRegion *mRegion;
- LLUUID mRegionUUID;
- bool mIsGetStatusOnly;
-};
-
-//---------------------------------------------------------------------------
-// NavMeshResponder
-//---------------------------------------------------------------------------
-
-class NavMeshResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(NavMeshResponder);
-public:
- NavMeshResponder(U32 pNavMeshVersion, LLPathfindingNavMeshPtr pNavMeshPtr);
- virtual ~NavMeshResponder();
-
-protected:
- virtual void httpSuccess();
- virtual void httpFailure();
-
-private:
- U32 mNavMeshVersion;
- LLPathfindingNavMeshPtr mNavMeshPtr;
-};
-
-//---------------------------------------------------------------------------
-// AgentStateResponder
-//---------------------------------------------------------------------------
-
-class AgentStateResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(AgentStateResponder);
-public:
- AgentStateResponder();
- virtual ~AgentStateResponder();
-
-protected:
- virtual void httpSuccess();
- virtual void httpFailure();
-};
-
-
-//---------------------------------------------------------------------------
-// NavMeshRebakeResponder
-//---------------------------------------------------------------------------
-class NavMeshRebakeResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(NavMeshRebakeResponder);
-public:
- NavMeshRebakeResponder(LLPathfindingManager::rebake_navmesh_callback_t pRebakeNavMeshCallback);
- virtual ~NavMeshRebakeResponder();
-
-protected:
- virtual void httpSuccess();
- virtual void httpFailure();
-
-private:
- LLPathfindingManager::rebake_navmesh_callback_t mRebakeNavMeshCallback;
-};
-
-//---------------------------------------------------------------------------
// LinksetsResponder
//---------------------------------------------------------------------------
@@ -188,6 +113,8 @@ public:
void handleTerrainLinksetsResult(const LLSD &pContent);
void handleTerrainLinksetsError();
+ typedef boost::shared_ptr<LinksetsResponder> ptr_t;
+
protected:
private:
@@ -214,64 +141,6 @@ private:
typedef boost::shared_ptr<LinksetsResponder> LinksetsResponderPtr;
//---------------------------------------------------------------------------
-// ObjectLinksetsResponder
-//---------------------------------------------------------------------------
-
-class ObjectLinksetsResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(ObjectLinksetsResponder);
-public:
- ObjectLinksetsResponder(LinksetsResponderPtr pLinksetsResponsderPtr);
- virtual ~ObjectLinksetsResponder();
-
-protected:
- virtual void httpSuccess();
- virtual void httpFailure();
-
-private:
- LinksetsResponderPtr mLinksetsResponsderPtr;
-};
-
-//---------------------------------------------------------------------------
-// TerrainLinksetsResponder
-//---------------------------------------------------------------------------
-
-class TerrainLinksetsResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(TerrainLinksetsResponder);
-public:
- TerrainLinksetsResponder(LinksetsResponderPtr pLinksetsResponsderPtr);
- virtual ~TerrainLinksetsResponder();
-
-protected:
- virtual void httpSuccess();
- virtual void httpFailure();
-
-private:
- LinksetsResponderPtr mLinksetsResponsderPtr;
-};
-
-//---------------------------------------------------------------------------
-// CharactersResponder
-//---------------------------------------------------------------------------
-
-class CharactersResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(TerrainLinksetsResponder);
-public:
- CharactersResponder(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::object_request_callback_t pCharactersCallback);
- virtual ~CharactersResponder();
-
-protected:
- virtual void httpSuccess();
- virtual void httpFailure();
-
-private:
- LLPathfindingManager::request_id_t mRequestId;
- LLPathfindingManager::object_request_callback_t mCharactersCallback;
-};
-
-//---------------------------------------------------------------------------
// LLPathfindingManager
//---------------------------------------------------------------------------
@@ -350,11 +219,13 @@ void LLPathfindingManager::requestGetNavMeshForRegion(LLViewerRegion *pRegion, b
}
else
{
- std::string navMeshStatusURL = getNavMeshStatusURLForRegion(pRegion);
- llassert(!navMeshStatusURL.empty());
- navMeshPtr->handleNavMeshCheckVersion();
- LLHTTPClient::ResponderPtr navMeshStatusResponder = new NavMeshStatusResponder(pRegion, pIsGetStatusOnly);
- LLHTTPClient::get(navMeshStatusURL, navMeshStatusResponder);
+ std::string navMeshStatusURL = getNavMeshStatusURLForRegion(pRegion);
+ llassert(!navMeshStatusURL.empty());
+ navMeshPtr->handleNavMeshCheckVersion();
+
+ U64 regionHandle = pRegion->getHandle();
+ std::string coroname = LLCoros::instance().launch("LLPathfindingManager::navMeshStatusRequestCoro",
+ boost::bind(&LLPathfindingManager::navMeshStatusRequestCoro, this, navMeshStatusURL, regionHandle, pIsGetStatusOnly));
}
}
@@ -385,15 +256,15 @@ void LLPathfindingManager::requestGetLinksets(request_id_t pRequestId, object_re
pLinksetsCallback(pRequestId, kRequestStarted, emptyLinksetListPtr);
bool doRequestTerrain = isAllowViewTerrainProperties();
- LinksetsResponderPtr linksetsResponderPtr(new LinksetsResponder(pRequestId, pLinksetsCallback, true, doRequestTerrain));
+ LinksetsResponder::ptr_t linksetsResponderPtr(new LinksetsResponder(pRequestId, pLinksetsCallback, true, doRequestTerrain));
- LLHTTPClient::ResponderPtr objectLinksetsResponder = new ObjectLinksetsResponder(linksetsResponderPtr);
- LLHTTPClient::get(objectLinksetsURL, objectLinksetsResponder);
+ std::string coroname = LLCoros::instance().launch("LLPathfindingManager::linksetObjectsCoro",
+ boost::bind(&LLPathfindingManager::linksetObjectsCoro, this, objectLinksetsURL, linksetsResponderPtr, LLSD()));
- if (doRequestTerrain)
+ if (doRequestTerrain)
{
- LLHTTPClient::ResponderPtr terrainLinksetsResponder = new TerrainLinksetsResponder(linksetsResponderPtr);
- LLHTTPClient::get(terrainLinksetsURL, terrainLinksetsResponder);
+ std::string coroname = LLCoros::instance().launch("LLPathfindingManager::linksetTerrainCoro",
+ boost::bind(&LLPathfindingManager::linksetTerrainCoro, this, terrainLinksetsURL, linksetsResponderPtr, LLSD()));
}
}
}
@@ -432,18 +303,18 @@ void LLPathfindingManager::requestSetLinksets(request_id_t pRequestId, const LLP
{
pLinksetsCallback(pRequestId, kRequestStarted, emptyLinksetListPtr);
- LinksetsResponderPtr linksetsResponderPtr(new LinksetsResponder(pRequestId, pLinksetsCallback, !objectPostData.isUndefined(), !terrainPostData.isUndefined()));
+ LinksetsResponder::ptr_t linksetsResponderPtr(new LinksetsResponder(pRequestId, pLinksetsCallback, !objectPostData.isUndefined(), !terrainPostData.isUndefined()));
if (!objectPostData.isUndefined())
{
- LLHTTPClient::ResponderPtr objectLinksetsResponder = new ObjectLinksetsResponder(linksetsResponderPtr);
- LLHTTPClient::put(objectLinksetsURL, objectPostData, objectLinksetsResponder);
+ std::string coroname = LLCoros::instance().launch("LLPathfindingManager::linksetObjectsCoro",
+ boost::bind(&LLPathfindingManager::linksetObjectsCoro, this, objectLinksetsURL, linksetsResponderPtr, objectPostData));
}
if (!terrainPostData.isUndefined())
{
- LLHTTPClient::ResponderPtr terrainLinksetsResponder = new TerrainLinksetsResponder(linksetsResponderPtr);
- LLHTTPClient::put(terrainLinksetsURL, terrainPostData, terrainLinksetsResponder);
+ std::string coroname = LLCoros::instance().launch("LLPathfindingManager::linksetTerrainCoro",
+ boost::bind(&LLPathfindingManager::linksetTerrainCoro, this, terrainLinksetsURL, linksetsResponderPtr, terrainPostData));
}
}
}
@@ -475,8 +346,8 @@ void LLPathfindingManager::requestGetCharacters(request_id_t pRequestId, object_
{
pCharactersCallback(pRequestId, kRequestStarted, emptyCharacterListPtr);
- LLHTTPClient::ResponderPtr charactersResponder = new CharactersResponder(pRequestId, pCharactersCallback);
- LLHTTPClient::get(charactersURL, charactersResponder);
+ std::string coroname = LLCoros::instance().launch("LLPathfindingManager::charactersCoro",
+ boost::bind(&LLPathfindingManager::charactersCoro, this, charactersURL, pRequestId, pCharactersCallback));
}
}
}
@@ -508,8 +379,9 @@ void LLPathfindingManager::requestGetAgentState()
{
std::string agentStateURL = getAgentStateURLForRegion(currentRegion);
llassert(!agentStateURL.empty());
- LLHTTPClient::ResponderPtr responder = new AgentStateResponder();
- LLHTTPClient::get(agentStateURL, responder);
+
+ std::string coroname = LLCoros::instance().launch("LLPathfindingManager::navAgentStateRequestCoro",
+ boost::bind(&LLPathfindingManager::navAgentStateRequestCoro, this, agentStateURL));
}
}
}
@@ -530,35 +402,9 @@ void LLPathfindingManager::requestRebakeNavMesh(rebake_navmesh_callback_t pRebak
{
std::string navMeshStatusURL = getNavMeshStatusURLForCurrentRegion();
llassert(!navMeshStatusURL.empty());
- LLSD postData;
- postData["command"] = "rebuild";
- LLHTTPClient::ResponderPtr responder = new NavMeshRebakeResponder(pRebakeNavMeshCallback);
- LLHTTPClient::post(navMeshStatusURL, postData, responder);
- }
-}
-
-void LLPathfindingManager::sendRequestGetNavMeshForRegion(LLPathfindingNavMeshPtr navMeshPtr, LLViewerRegion *pRegion, const LLPathfindingNavMeshStatus &pNavMeshStatus)
-{
- if ((pRegion == NULL) || !pRegion->isAlive())
- {
- navMeshPtr->handleNavMeshNotEnabled();
- }
- else
- {
- std::string navMeshURL = getRetrieveNavMeshURLForRegion(pRegion);
-
- if (navMeshURL.empty())
- {
- navMeshPtr->handleNavMeshNotEnabled();
- }
- else
- {
- navMeshPtr->handleNavMeshStart(pNavMeshStatus);
- LLHTTPClient::ResponderPtr responder = new NavMeshResponder(pNavMeshStatus.getVersion(), navMeshPtr);
- LLSD postData;
- LLHTTPClient::post(navMeshURL, postData, responder);
- }
+ std::string coroname = LLCoros::instance().launch("LLPathfindingManager::navMeshRebakeCoro",
+ boost::bind(&LLPathfindingManager::navMeshRebakeCoro, this, navMeshStatusURL, pRebakeNavMeshCallback));
}
}
@@ -602,29 +448,250 @@ void LLPathfindingManager::handleDeferredGetCharactersForRegion(const LLUUID &pR
}
}
-void LLPathfindingManager::handleNavMeshStatusRequest(const LLPathfindingNavMeshStatus &pNavMeshStatus, LLViewerRegion *pRegion, bool pIsGetStatusOnly)
+void LLPathfindingManager::navMeshStatusRequestCoro(std::string url, U64 regionHandle, bool isGetStatusOnly)
{
- LLPathfindingNavMeshPtr navMeshPtr = getNavMeshForRegion(pNavMeshStatus.getRegionUUID());
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("NavMeshStatusRequest", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLViewerRegion *region = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+ if (!region)
+ {
+ LL_WARNS("PathfindingManager") << "Attempting to retrieve navmesh status for region that has gone away." << LL_ENDL;
+ return;
+ }
+ LLUUID regionUUID = region->getRegionID();
+
+ region = NULL;
+ LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+ region = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
- if (!pNavMeshStatus.isValid())
- {
- navMeshPtr->handleNavMeshError();
- }
- else
- {
- if (navMeshPtr->hasNavMeshVersion(pNavMeshStatus))
- {
- navMeshPtr->handleRefresh(pNavMeshStatus);
- }
- else if (pIsGetStatusOnly)
- {
- navMeshPtr->handleNavMeshNewVersion(pNavMeshStatus);
- }
- else
- {
- sendRequestGetNavMeshForRegion(navMeshPtr, pRegion, pNavMeshStatus);
- }
- }
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ LLPathfindingNavMeshStatus navMeshStatus(regionUUID);
+ if (!status)
+ {
+ LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() <<
+ ". Building using empty status." << LL_ENDL;
+ }
+ else
+ {
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ navMeshStatus = LLPathfindingNavMeshStatus(regionUUID, result);
+ }
+
+ LLPathfindingNavMeshPtr navMeshPtr = getNavMeshForRegion(regionUUID);
+
+ if (!navMeshStatus.isValid())
+ {
+ navMeshPtr->handleNavMeshError();
+ return;
+ }
+ else if (navMeshPtr->hasNavMeshVersion(navMeshStatus))
+ {
+ navMeshPtr->handleRefresh(navMeshStatus);
+ return;
+ }
+ else if (isGetStatusOnly)
+ {
+ navMeshPtr->handleNavMeshNewVersion(navMeshStatus);
+ return;
+ }
+
+ if ((!region) || !region->isAlive())
+ {
+ LL_WARNS("PathfindingManager") << "About to update navmesh status for region that has gone away." << LL_ENDL;
+ navMeshPtr->handleNavMeshNotEnabled();
+ return;
+ }
+
+ std::string navMeshURL = getRetrieveNavMeshURLForRegion(region);
+
+ if (navMeshURL.empty())
+ {
+ navMeshPtr->handleNavMeshNotEnabled();
+ return;
+ }
+
+ navMeshPtr->handleNavMeshStart(navMeshStatus);
+
+ LLSD postData;
+ result = httpAdapter->postAndYield(httpRequest, navMeshURL, postData);
+
+ U32 navMeshVersion = navMeshStatus.getVersion();
+
+ if (!status)
+ {
+ LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() <<
+ ". reporting error." << LL_ENDL;
+ navMeshPtr->handleNavMeshError(navMeshVersion);
+ }
+ else
+ {
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ navMeshPtr->handleNavMeshResult(result, navMeshVersion);
+
+ }
+
+}
+
+void LLPathfindingManager::navAgentStateRequestCoro(std::string url)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("NavAgentStateRequest", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ bool canRebake = false;
+ if (!status)
+ {
+ LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() <<
+ ". Building using empty status." << LL_ENDL;
+ }
+ else
+ {
+ llassert(result.has(AGENT_STATE_CAN_REBAKE_REGION_FIELD));
+ llassert(result.get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).isBoolean());
+ canRebake = result.get(AGENT_STATE_CAN_REBAKE_REGION_FIELD).asBoolean();
+ }
+
+ handleAgentState(canRebake);
+}
+
+void LLPathfindingManager::navMeshRebakeCoro(std::string url, rebake_navmesh_callback_t rebakeNavMeshCallback)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("NavMeshRebake", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+
+ LLSD postData = LLSD::emptyMap();
+ postData["command"] = "rebuild";
+
+ LLSD result = httpAdapter->postAndYield(httpRequest, url, postData);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ bool success = true;
+ if (!status)
+ {
+ LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() <<
+ ". Rebake failed." << LL_ENDL;
+ success = false;
+ }
+
+ rebakeNavMeshCallback(success);
+}
+
+// If called with putData undefined this coroutine will issue a get. If there
+// is data in putData it will be PUT to the URL.
+void LLPathfindingManager::linksetObjectsCoro(std::string url, LinksetsResponder::ptr_t linksetsResponsderPtr, LLSD putData) const
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("LinksetObjects", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLSD result;
+
+ if (putData.isUndefined())
+ {
+ result = httpAdapter->getAndYield(httpRequest, url);
+ }
+ else
+ {
+ result = httpAdapter->putAndYield(httpRequest, url, putData);
+ }
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() <<
+ ". linksetObjects failed." << LL_ENDL;
+ linksetsResponsderPtr->handleObjectLinksetsError();
+ }
+ else
+ {
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ linksetsResponsderPtr->handleObjectLinksetsResult(result);
+ }
+}
+
+// If called with putData undefined this coroutine will issue a GET. If there
+// is data in putData it will be PUT to the URL.
+void LLPathfindingManager::linksetTerrainCoro(std::string url, LinksetsResponder::ptr_t linksetsResponsderPtr, LLSD putData) const
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("LinksetTerrain", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLSD result;
+
+ if (putData.isUndefined())
+ {
+ result = httpAdapter->getAndYield(httpRequest, url);
+ }
+ else
+ {
+ result = httpAdapter->putAndYield(httpRequest, url, putData);
+ }
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() <<
+ ". linksetTerrain failed." << LL_ENDL;
+ linksetsResponsderPtr->handleTerrainLinksetsError();
+ }
+ else
+ {
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ linksetsResponsderPtr->handleTerrainLinksetsResult(result);
+ }
+
+}
+
+void LLPathfindingManager::charactersCoro(std::string url, request_id_t requestId, object_request_callback_t callback) const
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("LinksetTerrain", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS("PathfindingManager") << "HTTP status, " << status.toTerseString() <<
+ ". characters failed." << LL_ENDL;
+
+ LLPathfindingObjectListPtr characterListPtr = LLPathfindingObjectListPtr(new LLPathfindingCharacterList());
+ callback(requestId, LLPathfindingManager::kRequestError, characterListPtr);
+ }
+ else
+ {
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ LLPathfindingObjectListPtr characterListPtr = LLPathfindingObjectListPtr(new LLPathfindingCharacterList(result));
+ callback(requestId, LLPathfindingManager::kRequestCompleted, characterListPtr);
+ }
}
void LLPathfindingManager::handleNavMeshStatusUpdate(const LLPathfindingNavMeshStatus &pNavMeshStatus)
@@ -765,121 +832,8 @@ void LLAgentStateChangeNode::post(ResponsePtr pResponse, const LLSD &pContext, c
}
//---------------------------------------------------------------------------
-// NavMeshStatusResponder
-//---------------------------------------------------------------------------
-
-NavMeshStatusResponder::NavMeshStatusResponder(LLViewerRegion *pRegion, bool pIsGetStatusOnly)
- : LLHTTPClient::Responder(),
- mRegion(pRegion),
- mRegionUUID(),
- mIsGetStatusOnly(pIsGetStatusOnly)
-{
- if (mRegion != NULL)
- {
- mRegionUUID = mRegion->getRegionID();
- }
-}
-
-NavMeshStatusResponder::~NavMeshStatusResponder()
-{
-}
-
-void NavMeshStatusResponder::httpSuccess()
-{
- LLPathfindingNavMeshStatus navMeshStatus(mRegionUUID, getContent());
- LLPathfindingManager::getInstance()->handleNavMeshStatusRequest(navMeshStatus, mRegion, mIsGetStatusOnly);
-}
-
-void NavMeshStatusResponder::httpFailure()
-{
- LL_WARNS() << dumpResponse() << LL_ENDL;
- LLPathfindingNavMeshStatus navMeshStatus(mRegionUUID);
- LLPathfindingManager::getInstance()->handleNavMeshStatusRequest(navMeshStatus, mRegion, mIsGetStatusOnly);
-}
-
-//---------------------------------------------------------------------------
-// NavMeshResponder
-//---------------------------------------------------------------------------
-
-NavMeshResponder::NavMeshResponder(U32 pNavMeshVersion, LLPathfindingNavMeshPtr pNavMeshPtr)
- : LLHTTPClient::Responder(),
- mNavMeshVersion(pNavMeshVersion),
- mNavMeshPtr(pNavMeshPtr)
-{
-}
-
-NavMeshResponder::~NavMeshResponder()
-{
-}
-
-void NavMeshResponder::httpSuccess()
-{
- mNavMeshPtr->handleNavMeshResult(getContent(), mNavMeshVersion);
-}
-
-void NavMeshResponder::httpFailure()
-{
- LL_WARNS() << dumpResponse() << LL_ENDL;
- mNavMeshPtr->handleNavMeshError(mNavMeshVersion);
-}
-
-//---------------------------------------------------------------------------
-// AgentStateResponder
-//---------------------------------------------------------------------------
-
-AgentStateResponder::AgentStateResponder()
-: LLHTTPClient::Responder()
-{
-}
-
-AgentStateResponder::~AgentStateResponder()
-{
-}
-
-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::httpFailure()
-{
- LL_WARNS() << dumpResponse() << LL_ENDL;
- LLPathfindingManager::getInstance()->handleAgentState(FALSE);
-}
-
-
-//---------------------------------------------------------------------------
-// navmesh rebake responder
-//---------------------------------------------------------------------------
-NavMeshRebakeResponder::NavMeshRebakeResponder(LLPathfindingManager::rebake_navmesh_callback_t pRebakeNavMeshCallback)
- : LLHTTPClient::Responder(),
- mRebakeNavMeshCallback(pRebakeNavMeshCallback)
-{
-}
-
-NavMeshRebakeResponder::~NavMeshRebakeResponder()
-{
-}
-
-void NavMeshRebakeResponder::httpSuccess()
-{
- mRebakeNavMeshCallback(true);
-}
-
-void NavMeshRebakeResponder::httpFailure()
-{
- LL_WARNS() << dumpResponse() << LL_ENDL;
- mRebakeNavMeshCallback(false);
-}
-
-//---------------------------------------------------------------------------
// LinksetsResponder
//---------------------------------------------------------------------------
-
LinksetsResponder::LinksetsResponder(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::object_request_callback_t pLinksetsCallback, bool pIsObjectRequested, bool pIsTerrainRequested)
: mRequestId(pRequestId),
mLinksetsCallback(pLinksetsCallback),
@@ -957,82 +911,3 @@ void LinksetsResponder::sendCallback()
mLinksetsCallback(mRequestId, requestStatus, mObjectLinksetListPtr);
}
-
-//---------------------------------------------------------------------------
-// ObjectLinksetsResponder
-//---------------------------------------------------------------------------
-
-ObjectLinksetsResponder::ObjectLinksetsResponder(LinksetsResponderPtr pLinksetsResponsderPtr)
- : LLHTTPClient::Responder(),
- mLinksetsResponsderPtr(pLinksetsResponsderPtr)
-{
-}
-
-ObjectLinksetsResponder::~ObjectLinksetsResponder()
-{
-}
-
-void ObjectLinksetsResponder::httpSuccess()
-{
- mLinksetsResponsderPtr->handleObjectLinksetsResult(getContent());
-}
-
-void ObjectLinksetsResponder::httpFailure()
-{
- LL_WARNS() << dumpResponse() << LL_ENDL;
- mLinksetsResponsderPtr->handleObjectLinksetsError();
-}
-
-//---------------------------------------------------------------------------
-// TerrainLinksetsResponder
-//---------------------------------------------------------------------------
-
-TerrainLinksetsResponder::TerrainLinksetsResponder(LinksetsResponderPtr pLinksetsResponsderPtr)
- : LLHTTPClient::Responder(),
- mLinksetsResponsderPtr(pLinksetsResponsderPtr)
-{
-}
-
-TerrainLinksetsResponder::~TerrainLinksetsResponder()
-{
-}
-
-void TerrainLinksetsResponder::httpSuccess()
-{
- mLinksetsResponsderPtr->handleTerrainLinksetsResult(getContent());
-}
-
-void TerrainLinksetsResponder::httpFailure()
-{
- LL_WARNS() << dumpResponse() << LL_ENDL;
- mLinksetsResponsderPtr->handleTerrainLinksetsError();
-}
-
-//---------------------------------------------------------------------------
-// CharactersResponder
-//---------------------------------------------------------------------------
-
-CharactersResponder::CharactersResponder(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::object_request_callback_t pCharactersCallback)
- : LLHTTPClient::Responder(),
- mRequestId(pRequestId),
- mCharactersCallback(pCharactersCallback)
-{
-}
-
-CharactersResponder::~CharactersResponder()
-{
-}
-
-void CharactersResponder::httpSuccess()
-{
- LLPathfindingObjectListPtr characterListPtr = LLPathfindingObjectListPtr(new LLPathfindingCharacterList(getContent()));
- mCharactersCallback(mRequestId, LLPathfindingManager::kRequestCompleted, characterListPtr);
-}
-
-void CharactersResponder::httpFailure()
-{
- LL_WARNS() << dumpResponse() << LL_ENDL;
-
- LLPathfindingObjectListPtr characterListPtr = LLPathfindingObjectListPtr(new LLPathfindingCharacterList());
- mCharactersCallback(mRequestId, LLPathfindingManager::kRequestError, characterListPtr);
-}
diff --git a/indra/newview/llpathfindingmanager.h b/indra/newview/llpathfindingmanager.h
index c61ff244fc..e8fad590ba 100755
--- a/indra/newview/llpathfindingmanager.h
+++ b/indra/newview/llpathfindingmanager.h
@@ -37,11 +37,15 @@
#include "llpathfindingobjectlist.h"
#include "llpathfindingnavmesh.h"
#include "llsingleton.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
class LLPathfindingNavMeshStatus;
class LLUUID;
class LLViewerRegion;
+class LinksetsResponder;
+
class LLPathfindingManager : public LLSingleton<LLPathfindingManager>
{
friend class LLNavMeshSimStateChangeNode;
@@ -92,16 +96,22 @@ public:
protected:
private:
- typedef std::map<LLUUID, LLPathfindingNavMeshPtr> NavMeshMap;
- void sendRequestGetNavMeshForRegion(LLPathfindingNavMeshPtr navMeshPtr, LLViewerRegion *pRegion, const LLPathfindingNavMeshStatus &pNavMeshStatus);
+ typedef std::map<LLUUID, LLPathfindingNavMeshPtr> NavMeshMap;
void handleDeferredGetAgentStateForRegion(const LLUUID &pRegionUUID);
void handleDeferredGetNavMeshForRegion(const LLUUID &pRegionUUID, bool pIsGetStatusOnly);
void handleDeferredGetLinksetsForRegion(const LLUUID &pRegionUUID, request_id_t pRequestId, object_request_callback_t pLinksetsCallback) const;
void handleDeferredGetCharactersForRegion(const LLUUID &pRegionUUID, request_id_t pRequestId, object_request_callback_t pCharactersCallback) const;
- void handleNavMeshStatusRequest(const LLPathfindingNavMeshStatus &pNavMeshStatus, LLViewerRegion *pRegion, bool pIsGetStatusOnly);
+ void navMeshStatusRequestCoro(std::string url, U64 regionHandle, bool isGetStatusOnly);
+ void navAgentStateRequestCoro(std::string url);
+ void navMeshRebakeCoro(std::string url, rebake_navmesh_callback_t rebakeNavMeshCallback);
+ void linksetObjectsCoro(std::string url, boost::shared_ptr<LinksetsResponder> linksetsResponsderPtr, LLSD putData) const;
+ void linksetTerrainCoro(std::string url, boost::shared_ptr<LinksetsResponder> linksetsResponsderPtr, LLSD putData) const;
+ void charactersCoro(std::string url, request_id_t requestId, object_request_callback_t callback) const;
+
+ //void handleNavMeshStatusRequest(const LLPathfindingNavMeshStatus &pNavMeshStatus, LLViewerRegion *pRegion, bool pIsGetStatusOnly);
void handleNavMeshStatusUpdate(const LLPathfindingNavMeshStatus &pNavMeshStatus);
void handleAgentState(BOOL pCanRebakeRegion);
diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp
index c378738b05..c1d1b9b03c 100755
--- a/indra/newview/llpreviewgesture.cpp
+++ b/indra/newview/llpreviewgesture.cpp
@@ -52,6 +52,7 @@
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
#include "llviewerstats.h"
+#include "llviewerassetupload.h"
std::string NONE_LABEL;
std::string SHIFT_LABEL;
@@ -1015,6 +1016,27 @@ struct LLSaveInfo
};
+void finishInventoryUpload(LLUUID itemId, LLUUID newAssetId)
+{
+ // If this gesture is active, then we need to update the in-memory
+ // active map with the new pointer.
+ if (LLGestureMgr::instance().isGestureActive(itemId))
+ {
+ //*TODO: This is crashing for some reason. Fix it.
+ // Active gesture edited from menu.
+ LLGestureMgr::instance().replaceGesture(itemId, newAssetId);
+ gInventory.notifyObservers();
+ }
+
+ //gesture will have a new asset_id
+ LLPreviewGesture* previewp = LLFloaterReg::findTypedInstance<LLPreviewGesture>("preview_gesture", LLSD(itemId));
+ if (previewp)
+ {
+ previewp->onUpdateSucceeded();
+ }
+}
+
+
void LLPreviewGesture::saveIfNeeded()
{
if (!gAssetStorage)
@@ -1028,116 +1050,127 @@ void LLPreviewGesture::saveIfNeeded()
return;
}
- // Copy the UI into a gesture
- LLMultiGesture* gesture = createGesture();
-
- // Serialize the gesture
- S32 max_size = gesture->getMaxSerialSize();
- char* buffer = new char[max_size];
-
- LLDataPackerAsciiBuffer dp(buffer, max_size);
-
- BOOL ok = gesture->serialize(dp);
-
- if (dp.getCurrentSize() > 1000)
- {
- LLNotificationsUtil::add("GestureSaveFailedTooManySteps");
-
- delete gesture;
- gesture = NULL;
- }
- else if (!ok)
- {
- LLNotificationsUtil::add("GestureSaveFailedTryAgain");
- delete gesture;
- gesture = NULL;
- }
- else
- {
- LLPreview::onCommit();
-
- // Every save gets a new UUID. Yup.
- LLTransactionID tid;
- LLAssetID asset_id;
- tid.generate();
- asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
-
- LLVFile file(gVFS, asset_id, LLAssetType::AT_GESTURE, LLVFile::APPEND);
-
- S32 size = dp.getCurrentSize();
- file.setMaxSize(size);
- file.write((U8*)buffer, size);
-
- BOOL delayedUpload = FALSE;
-
- // Upload that asset to the database
- LLViewerInventoryItem* item = (LLViewerInventoryItem*) getItem();
- if (item)
- {
- std::string agent_url = gAgent.getRegion()->getCapability("UpdateGestureAgentInventory");
- std::string task_url = gAgent.getRegion()->getCapability("UpdateGestureTaskInventory");
- if (mObjectUUID.isNull() && !agent_url.empty())
- {
- //need to disable the preview floater so item
- //isn't re-saved before new asset arrives
- //fake out refresh.
- item->setComplete(FALSE);
- refresh();
- item->setComplete(TRUE);
-
- // Saving into agent inventory
- LLSD body;
- body["item_id"] = mItemUUID;
- LLHTTPClient::post(agent_url, body,
- new LLUpdateAgentInventoryResponder(body, asset_id, LLAssetType::AT_GESTURE));
- delayedUpload = TRUE;
- }
- else if (!mObjectUUID.isNull() && !task_url.empty())
- {
- // Saving into task inventory
- LLSD body;
- body["task_id"] = mObjectUUID;
- body["item_id"] = mItemUUID;
- LLHTTPClient::post(task_url, body,
- new LLUpdateTaskInventoryResponder(body, asset_id, LLAssetType::AT_GESTURE));
- }
- else if (gAssetStorage)
- {
- LLLineEditor* descEditor = getChild<LLLineEditor>("desc");
- LLSaveInfo* info = new LLSaveInfo(mItemUUID, mObjectUUID, descEditor->getText(), tid);
- gAssetStorage->storeAssetData(tid, LLAssetType::AT_GESTURE, onSaveComplete, info, FALSE);
- }
- }
-
- // If this gesture is active, then we need to update the in-memory
- // active map with the new pointer.
- if (!delayedUpload && LLGestureMgr::instance().isGestureActive(mItemUUID))
- {
- // gesture manager now owns the pointer
- LLGestureMgr::instance().replaceGesture(mItemUUID, gesture, asset_id);
-
- // replaceGesture may deactivate other gestures so let the
- // inventory know.
- gInventory.notifyObservers();
- }
- else
- {
- // we're done with this gesture
- delete gesture;
- gesture = NULL;
- }
-
- mDirty = FALSE;
- // refresh will be called when callback
- // if triggered when delayedUpload
- if(!delayedUpload)
- {
- refresh();
- }
- }
+ // Copy the UI into a gesture
+ LLMultiGesture* gesture = createGesture();
+
+ // Serialize the gesture
+ S32 maxSize = gesture->getMaxSerialSize();
+ char* buffer = new char[maxSize];
+
+ LLDataPackerAsciiBuffer dp(buffer, maxSize);
+
+ bool ok = gesture->serialize(dp);
+
+ if (dp.getCurrentSize() > 1000)
+ {
+ LLNotificationsUtil::add("GestureSaveFailedTooManySteps");
+
+ delete gesture;
+ gesture = NULL;
+ return;
+ }
+ else if (!ok)
+ {
+ LLNotificationsUtil::add("GestureSaveFailedTryAgain");
+ delete gesture;
+ gesture = NULL;
+ return;
+ }
+
+ LLAssetID assetId;
+ LLPreview::onCommit();
+ bool delayedUpload(false);
+
+ LLViewerInventoryItem* item = (LLViewerInventoryItem*) getItem();
+ if (item)
+ {
+ const LLViewerRegion* region = gAgent.getRegion();
+ if (!region)
+ {
+ LL_WARNS() << "Not connected to a region, cannot save notecard." << LL_ENDL;
+ return;
+ }
+ std::string agent_url = region->getCapability("UpdateGestureAgentInventory");
+ std::string task_url = region->getCapability("UpdateGestureTaskInventory");
+
+ if (!agent_url.empty() && !task_url.empty())
+ {
+ std::string url;
+ LLResourceUploadInfo::ptr_t uploadInfo;
+
+ if (mObjectUUID.isNull() && !agent_url.empty())
+ {
+ //need to disable the preview floater so item
+ //isn't re-saved before new asset arrives
+ //fake out refresh.
+ item->setComplete(false);
+ refresh();
+ item->setComplete(true);
+
+ uploadInfo = LLResourceUploadInfo::ptr_t(new LLBufferedAssetUploadInfo(mItemUUID, LLAssetType::AT_GESTURE, buffer,
+ boost::bind(&finishInventoryUpload, _1, _2)));
+ url = agent_url;
+ }
+ else if (!mObjectUUID.isNull() && !task_url.empty())
+ {
+ uploadInfo = LLResourceUploadInfo::ptr_t(new LLBufferedAssetUploadInfo(mObjectUUID, mItemUUID, LLAssetType::AT_GESTURE, buffer, NULL));
+ url = task_url;
+ }
+
+ if (!url.empty() && uploadInfo)
+ {
+ delayedUpload = true;
+
+ LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo);
+ }
+
+ }
+ else if (gAssetStorage)
+ {
+ // Every save gets a new UUID. Yup.
+ LLTransactionID tid;
+ tid.generate();
+ assetId = tid.makeAssetID(gAgent.getSecureSessionID());
+
+ LLVFile file(gVFS, assetId, LLAssetType::AT_GESTURE, LLVFile::APPEND);
+
+ S32 size = dp.getCurrentSize();
+ file.setMaxSize(size);
+ file.write((U8*)buffer, size);
+
+ LLLineEditor* descEditor = getChild<LLLineEditor>("desc");
+ LLSaveInfo* info = new LLSaveInfo(mItemUUID, mObjectUUID, descEditor->getText(), tid);
+ gAssetStorage->storeAssetData(tid, LLAssetType::AT_GESTURE, onSaveComplete, info, FALSE);
+ }
+
+ }
+
+ // If this gesture is active, then we need to update the in-memory
+ // active map with the new pointer.
+ if (!delayedUpload && LLGestureMgr::instance().isGestureActive(mItemUUID))
+ {
+ // gesture manager now owns the pointer
+ LLGestureMgr::instance().replaceGesture(mItemUUID, gesture, assetId);
+
+ // replaceGesture may deactivate other gestures so let the
+ // inventory know.
+ gInventory.notifyObservers();
+ }
+ else
+ {
+ // we're done with this gesture
+ delete gesture;
+ gesture = NULL;
+ }
+
+ mDirty = false;
+ // refresh will be called when callback
+ // if triggered when delayedUpload
+ if(!delayedUpload)
+ {
+ refresh();
+ }
- delete [] buffer;
- buffer = NULL;
}
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index 1308d1e9a7..be44fbd300 100755
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -56,6 +56,7 @@
#include "llappviewer.h" // app_abort_quit()
#include "lllineeditor.h"
#include "lluictrlfactory.h"
+#include "llviewerassetupload.h"
///----------------------------------------------------------------------------
/// Class LLPreviewNotecard
@@ -404,6 +405,35 @@ struct LLSaveNotecardInfo
}
};
+void finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId)
+{
+ // Update the UI with the new asset.
+ LLPreviewNotecard* nc = LLFloaterReg::findTypedInstance<LLPreviewNotecard>("preview_notecard", LLSD(itemId));
+ if (nc)
+ {
+ // *HACK: we have to delete the asset in the VFS so
+ // that the viewer will redownload it. This is only
+ // really necessary if the asset had to be modified by
+ // the uploader, so this can be optimized away in some
+ // cases. A better design is to have a new uuid if the
+ // script actually changed the asset.
+ if (nc->hasEmbeddedInventory())
+ {
+ gVFS->removeFile(newAssetId, LLAssetType::AT_NOTECARD);
+ }
+ if (newItemId.isNull())
+ {
+ nc->setAssetId(newAssetId);
+ nc->refreshFromInventory();
+ }
+ else
+ {
+ nc->refreshFromInventory(newItemId);
+ }
+ }
+}
+
+
bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem)
{
LLViewerTextEditor* editor = getChild<LLViewerTextEditor>("Notecard Editor");
@@ -416,14 +446,6 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem)
if(!editor->isPristine())
{
- // We need to update the asset information
- LLTransactionID tid;
- LLAssetID asset_id;
- tid.generate();
- asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
-
- LLVFile file(gVFS, asset_id, LLAssetType::AT_NOTECARD, LLVFile::APPEND);
-
std::string buffer;
if (!editor->exportBuffer(buffer))
{
@@ -432,52 +454,64 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem)
editor->makePristine();
- S32 size = buffer.length() + 1;
- file.setMaxSize(size);
- file.write((U8*)buffer.c_str(), size);
-
const LLInventoryItem* item = getItem();
// save it out to database
- if (item)
- {
- const LLViewerRegion* region = gAgent.getRegion();
- if (!region)
- {
- LL_WARNS() << "Not connected to a region, cannot save notecard." << LL_ENDL;
- return false;
- }
- std::string agent_url = region->getCapability("UpdateNotecardAgentInventory");
- std::string task_url = region->getCapability("UpdateNotecardTaskInventory");
-
- if (mObjectUUID.isNull() && !agent_url.empty())
- {
- // Saving into agent inventory
- mAssetStatus = PREVIEW_ASSET_LOADING;
- setEnabled(FALSE);
- LLSD body;
- body["item_id"] = mItemUUID;
- LL_INFOS() << "Saving notecard " << mItemUUID
- << " into agent inventory via " << agent_url << LL_ENDL;
- LLHTTPClient::post(agent_url, body,
- new LLUpdateAgentInventoryResponder(body, asset_id, LLAssetType::AT_NOTECARD));
- }
- else if (!mObjectUUID.isNull() && !task_url.empty())
- {
- // Saving into task inventory
- mAssetStatus = PREVIEW_ASSET_LOADING;
- setEnabled(FALSE);
- LLSD body;
- body["task_id"] = mObjectUUID;
- body["item_id"] = mItemUUID;
- LL_INFOS() << "Saving notecard " << mItemUUID << " into task "
- << mObjectUUID << " via " << task_url << LL_ENDL;
- LLHTTPClient::post(task_url, body,
- new LLUpdateTaskInventoryResponder(body, asset_id, LLAssetType::AT_NOTECARD));
- }
+ if (item)
+ {
+ const LLViewerRegion* region = gAgent.getRegion();
+ if (!region)
+ {
+ LL_WARNS() << "Not connected to a region, cannot save notecard." << LL_ENDL;
+ return false;
+ }
+ std::string agent_url = region->getCapability("UpdateNotecardAgentInventory");
+ std::string task_url = region->getCapability("UpdateNotecardTaskInventory");
+
+ if (!agent_url.empty() && !task_url.empty())
+ {
+ std::string url;
+ LLResourceUploadInfo::ptr_t uploadInfo;
+
+ if (mObjectUUID.isNull() && !agent_url.empty())
+ {
+ uploadInfo = LLResourceUploadInfo::ptr_t(new LLBufferedAssetUploadInfo(mItemUUID, LLAssetType::AT_NOTECARD, buffer,
+ boost::bind(&finishInventoryUpload, _1, _2, _3)));
+ url = agent_url;
+ }
+ else if (!mObjectUUID.isNull() && !task_url.empty())
+ {
+ uploadInfo = LLResourceUploadInfo::ptr_t(new LLBufferedAssetUploadInfo(mObjectUUID, mItemUUID, LLAssetType::AT_NOTECARD, buffer,
+ boost::bind(&finishInventoryUpload, _1, _3, LLUUID::null)));
+ url = task_url;
+ }
+
+ if (!url.empty() && uploadInfo)
+ {
+ mAssetStatus = PREVIEW_ASSET_LOADING;
+ setEnabled(false);
+
+ LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo);
+ }
+
+ }
else if (gAssetStorage)
{
+ // We need to update the asset information
+ LLTransactionID tid;
+ LLAssetID asset_id;
+ tid.generate();
+ asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
+
+ LLVFile file(gVFS, asset_id, LLAssetType::AT_NOTECARD, LLVFile::APPEND);
+
+
LLSaveNotecardInfo* info = new LLSaveNotecardInfo(this, mItemUUID, mObjectUUID,
tid, copyitem);
+
+ S32 size = buffer.length() + 1;
+ file.setMaxSize(size);
+ file.write((U8*)buffer.c_str(), size);
+
gAssetStorage->storeAssetData(tid, LLAssetType::AT_NOTECARD,
&onSaveComplete,
(void*)info,
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 1bbb22416d..fc565ffa20 100755
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -89,6 +89,7 @@
#include "llexperiencecache.h"
#include "llfloaterexperienceprofile.h"
#include "llexperienceassociationresponder.h"
+#include "llviewerassetupload.h"
const std::string HELLO_LSL =
"default\n"
@@ -1641,20 +1642,79 @@ void LLPreviewLSL::onSave(void* userdata, BOOL close_after_save)
self->saveIfNeeded();
}
+void finishedLSLUpload(LLUUID itemId, LLSD response)
+{
+ // Find our window and close it if requested.
+ LLPreviewLSL* preview = LLFloaterReg::findTypedInstance<LLPreviewLSL>("preview_script", LLSD(itemId));
+ if (preview)
+ {
+ // Bytecode save completed
+ if (response["compiled"])
+ {
+ preview->callbackLSLCompileSucceeded();
+ }
+ else
+ {
+ preview->callbackLSLCompileFailed(response["errors"]);
+ }
+ }
+}
+
// Save needs to compile the text in the buffer. If the compile
// succeeds, then save both assets out to the database. If the compile
// fails, go ahead and save the text anyway.
void LLPreviewLSL::saveIfNeeded(bool sync /*= true*/)
{
+ if (!mScriptEd->hasChanged())
+ {
+ return;
+ }
+
+ mPendingUploads = 0;
+ mScriptEd->mErrorList->deleteAllItems();
+ mScriptEd->mEditor->makePristine();
+
+#if 1
+ if (sync)
+ {
+ mScriptEd->sync();
+ }
+
+ const LLInventoryItem *inv_item = getItem();
+ // save it out to asset server
+ std::string url = gAgent.getRegion()->getCapability("UpdateScriptAgent");
+ if(inv_item)
+ {
+ getWindow()->incBusyCount();
+ mPendingUploads++;
+ if (!url.empty())
+ {
+ std::string buffer(mScriptEd->mEditor->getText());
+ LLBufferedAssetUploadInfo::invnUploadFinish_f proc = boost::bind(&finishedLSLUpload, _1, _4);
+
+ LLResourceUploadInfo::ptr_t uploadInfo(new LLScriptAssetUpload(mItemUUID, buffer, proc));
+
+ LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo);
+
+ }
+ else if (gAssetStorage)
+ {
+ // save off asset into file
+ LLTransactionID tid;
+ tid.generate();
+ LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
+ std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, asset_id.asString());
+ std::string filename = filepath + ".lsl";
+
+ mScriptEd->writeToFile(filename);
+
+ uploadAssetLegacy(filename, mItemUUID, tid);
+ }
+ }
+
+
+#else
// LL_INFOS() << "LLPreviewLSL::saveIfNeeded()" << LL_ENDL;
- if(!mScriptEd->hasChanged())
- {
- return;
- }
-
- mPendingUploads = 0;
- mScriptEd->mErrorList->deleteAllItems();
- mScriptEd->mEditor->makePristine();
// save off asset into file
LLTransactionID tid;
@@ -1686,8 +1746,10 @@ void LLPreviewLSL::saveIfNeeded(bool sync /*= true*/)
uploadAssetLegacy(filename, mItemUUID, tid);
}
}
+#endif
}
+#if 0
void LLPreviewLSL::uploadAssetViaCaps(const std::string& url,
const std::string& filename,
const LLUUID& item_id)
@@ -1698,6 +1760,7 @@ void LLPreviewLSL::uploadAssetViaCaps(const std::string& url,
body["target"] = "lsl2";
LLHTTPClient::post(url, body, new LLUpdateAgentInventoryResponder(body, filename, LLAssetType::AT_LSL_TEXT));
}
+#endif
void LLPreviewLSL::uploadAssetLegacy(const std::string& filename,
const LLUUID& item_id,
diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h
index 5f65be7383..954d040bda 100755
--- a/indra/newview/llpreviewscript.h
+++ b/indra/newview/llpreviewscript.h
@@ -203,9 +203,11 @@ protected:
virtual void loadAsset();
/*virtual*/ void saveIfNeeded(bool sync = true);
+#if 0
void uploadAssetViaCaps(const std::string& url,
const std::string& filename,
const LLUUID& item_id);
+#endif // 0
void uploadAssetLegacy(const std::string& filename,
const LLUUID& item_id,
const LLTransactionID& tid);
diff --git a/indra/newview/llproductinforequest.cpp b/indra/newview/llproductinforequest.cpp
index e92bf4590d..467e9df482 100755
--- a/indra/newview/llproductinforequest.cpp
+++ b/indra/newview/llproductinforequest.cpp
@@ -32,31 +32,10 @@
#include "llagent.h" // for gAgent
#include "lltrans.h"
#include "llviewerregion.h"
+#include "llcorehttputil.h"
-class LLProductInfoRequestResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(LLProductInfoRequestResponder);
-private:
- //If we get back a normal response, handle it here
- /* virtual */ void httpSuccess()
- {
- 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 httpFailure()
- {
- LL_WARNS() << dumpResponse() << LL_ENDL;
- }
-};
-
-LLProductInfoRequestManager::LLProductInfoRequestManager() : mSkuDescriptions()
+LLProductInfoRequestManager::LLProductInfoRequestManager():
+ mSkuDescriptions()
{
}
@@ -65,15 +44,11 @@ void LLProductInfoRequestManager::initSingleton()
std::string url = gAgent.getRegion()->getCapability("ProductInfoRequest");
if (!url.empty())
{
- LLHTTPClient::get(url, new LLProductInfoRequestResponder());
+ LLCoros::instance().launch("LLProductInfoRequestManager::getLandDescriptionsCoro",
+ boost::bind(&LLProductInfoRequestManager::getLandDescriptionsCoro, this, url));
}
}
-void LLProductInfoRequestManager::setSkuDescriptions(const LLSD& content)
-{
- mSkuDescriptions = content;
-}
-
std::string LLProductInfoRequestManager::getDescriptionForSku(const std::string& sku)
{
// The description LLSD is an array of maps; each array entry
@@ -90,3 +65,31 @@ std::string LLProductInfoRequestManager::getDescriptionForSku(const std::string&
}
return LLTrans::getString("land_type_unknown");
}
+
+void LLProductInfoRequestManager::getLandDescriptionsCoro(std::string url)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("genericPostCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ return;
+ }
+
+ if (result.has(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT) &&
+ result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT].isArray())
+ {
+ mSkuDescriptions = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT];
+ }
+ else
+ {
+ LL_WARNS() << "Land SKU description response is malformed" << LL_ENDL;
+ }
+}
diff --git a/indra/newview/llproductinforequest.h b/indra/newview/llproductinforequest.h
index fe8f7093b0..75dbf220d1 100755
--- a/indra/newview/llproductinforequest.h
+++ b/indra/newview/llproductinforequest.h
@@ -28,27 +28,29 @@
#ifndef LL_LLPRODUCTINFOREQUEST_H
#define LL_LLPRODUCTINFOREQUEST_H
-#include "llhttpclient.h"
#include "llmemory.h"
+#include "lleventcoro.h"
+#include "llcoros.h"
-/*
- This is a singleton to manage a cache of information about land types.
- The land system provides a capability to get information about the
- set of possible land sku, name, and description information.
- We use description in the UI, but the sku is provided in the various
- messages; this tool provides translation between the systems.
+/**
+ * This is a singleton to manage a cache of information about land types.
+ * The land system provides a capability to get information about the
+ * set of possible land sku, name, and description information.
+ * We use description in the UI, but the sku is provided in the various
+ * messages; this tool provides translation between the systems.
*/
-
class LLProductInfoRequestManager : public LLSingleton<LLProductInfoRequestManager>
{
public:
LLProductInfoRequestManager();
- void setSkuDescriptions(const LLSD& content);
std::string getDescriptionForSku(const std::string& sku);
+
private:
friend class LLSingleton<LLProductInfoRequestManager>;
/* virtual */ void initSingleton();
- LLSD mSkuDescriptions;
+
+ void getLandDescriptionsCoro(std::string url);
+ LLSD mSkuDescriptions;
};
#endif // LL_LLPRODUCTINFOREQUEST_H
diff --git a/indra/newview/llremoteparcelrequest.cpp b/indra/newview/llremoteparcelrequest.cpp
index 29dcc12f9e..06bf90c7cb 100755
--- a/indra/newview/llremoteparcelrequest.cpp
+++ b/indra/newview/llremoteparcelrequest.cpp
@@ -31,55 +31,16 @@
#include "message.h"
#include "llpanel.h"
-#include "llhttpclient.h"
#include "llsdserialize.h"
#include "llurlentry.h"
#include "llviewerregion.h"
#include "llview.h"
-
+#include "llsdutil.h"
+#include "llsdutil_math.h"
+#include "llregionhandle.h"
#include "llagent.h"
#include "llremoteparcelrequest.h"
-
-
-LLRemoteParcelRequestResponder::LLRemoteParcelRequestResponder(LLHandle<LLRemoteParcelInfoObserver> observer_handle)
- : mObserverHandle(observer_handle)
-{}
-
-//If we get back a normal response, handle it here
-//virtual
-void LLRemoteParcelRequestResponder::httpSuccess()
-{
- 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.
- LLRemoteParcelInfoObserver* observer = mObserverHandle.get();
- if (observer)
- {
- observer->setParcelID(parcel_id);
- }
-}
-
-//If we get back an error (not found, etc...), handle it here
-//virtual
-void LLRemoteParcelRequestResponder::httpFailure()
-{
- LL_WARNS() << dumpResponse() << LL_ENDL;
-
- // Panel inspecting the information may be closed and destroyed
- // before this response is received.
- LLRemoteParcelInfoObserver* observer = mObserverHandle.get();
- if (observer)
- {
- observer->setErrorStatus(getStatus(), getReason());
- }
-}
+#include "llcorehttputil.h"
void LLRemoteParcelInfoProcessor::addObserver(const LLUUID& parcel_id, LLRemoteParcelInfoObserver* observer)
{
@@ -200,3 +161,64 @@ void LLRemoteParcelInfoProcessor::sendParcelInfoRequest(const LLUUID& parcel_id)
msg->addUUID("ParcelID", parcel_id);
gAgent.sendReliableMessage();
}
+
+bool LLRemoteParcelInfoProcessor::requestRegionParcelInfo(const std::string &url,
+ const LLUUID &regionId, const LLVector3 &regionPos, const LLVector3d&globalPos,
+ LLHandle<LLRemoteParcelInfoObserver> observerHandle)
+{
+
+ if (!url.empty())
+ {
+ LLCoros::instance().launch("LLRemoteParcelInfoProcessor::regionParcelInfoCoro",
+ boost::bind(&LLRemoteParcelInfoProcessor::regionParcelInfoCoro, this, url,
+ regionId, regionPos, globalPos, observerHandle));
+ return true;
+ }
+
+ return false;
+}
+
+void LLRemoteParcelInfoProcessor::regionParcelInfoCoro(std::string url,
+ LLUUID regionId, LLVector3 posRegion, LLVector3d posGlobal,
+ LLHandle<LLRemoteParcelInfoObserver> observerHandle)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("RemoteParcelRequest", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLSD bodyData;
+
+ bodyData["location"] = ll_sd_from_vector3(posRegion);
+ if (!regionId.isNull())
+ {
+ bodyData["region_id"] = regionId;
+ }
+ if (!posGlobal.isExactlyZero())
+ {
+ U64 regionHandle = to_region_handle(posGlobal);
+ bodyData["region_handle"] = ll_sd_from_U64(regionHandle);
+ }
+
+ LLSD result = httpAdapter->postAndYield(httpRequest, url, bodyData);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ LLRemoteParcelInfoObserver* observer = observerHandle.get();
+ // Panel inspecting the information may be closed and destroyed
+ // before this response is received.
+ if (!observer)
+ return;
+
+ if (!status)
+ {
+ observer->setErrorStatus(status.getStatus(), status.getMessage());
+ }
+ else
+ {
+ LLUUID parcel_id = result["parcel_id"];
+ observer->setParcelID(parcel_id);
+ }
+
+}
diff --git a/indra/newview/llremoteparcelrequest.h b/indra/newview/llremoteparcelrequest.h
index 35348b69ff..cb5af50c5f 100755
--- a/indra/newview/llremoteparcelrequest.h
+++ b/indra/newview/llremoteparcelrequest.h
@@ -29,29 +29,14 @@
#ifndef LL_LLREMOTEPARCELREQUEST_H
#define LL_LLREMOTEPARCELREQUEST_H
-#include "llhttpclient.h"
#include "llhandle.h"
#include "llsingleton.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
class LLMessageSystem;
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 httpSuccess();
-
- //If we get back an error (not found, etc...), handle it here
- /*virtual*/ void httpFailure();
-
- LLHandle<LLRemoteParcelInfoObserver> mObserverHandle;
-};
-
struct LLParcelData
{
LLUUID parcel_id;
@@ -99,9 +84,14 @@ public:
static void processParcelInfoReply(LLMessageSystem* msg, void**);
+ bool requestRegionParcelInfo(const std::string &url, const LLUUID &regionId,
+ const LLVector3 &regionPos, const LLVector3d& globalPos, LLHandle<LLRemoteParcelInfoObserver> observerHandle);
+
private:
typedef std::multimap<LLUUID, LLHandle<LLRemoteParcelInfoObserver> > observer_multimap_t;
observer_multimap_t mObservers;
+
+ void regionParcelInfoCoro(std::string url, LLUUID regionId, LLVector3 posRegion, LLVector3d posGlobal, LLHandle<LLRemoteParcelInfoObserver> observerHandle);
};
#endif // LL_LLREMOTEPARCELREQUEST_H
diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp
index 0ae8a338e0..16f70a1c95 100644
--- a/indra/newview/llsnapshotlivepreview.cpp
+++ b/indra/newview/llsnapshotlivepreview.cpp
@@ -1004,9 +1004,23 @@ void LLSnapshotLivePreview::saveTexture()
LLAgentUI::buildLocationString(pos_string, LLAgentUI::LOCATION_FORMAT_FULL);
std::string who_took_it;
LLAgentUI::buildFullname(who_took_it);
- LLAssetStorage::LLStoreAssetCallback callback = NULL;
S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
- void *userdata = NULL;
+#if 1
+ std::string name = "Snapshot: " + pos_string;
+ std::string desc = "Taken by " + who_took_it + " at " + pos_string;
+
+ LLResourceUploadInfo::ptr_t assetUploadInfo(new LLResourceUploadInfo(
+ tid, LLAssetType::AT_TEXTURE, name, desc, 0,
+ LLFolderType::FT_SNAPSHOT_CATEGORY, LLInventoryType::IT_SNAPSHOT,
+ PERM_ALL, LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"),
+ expected_upload_cost));
+
+ upload_new_resource(assetUploadInfo);
+
+#else
+ LLAssetStorage::LLStoreAssetCallback callback = NULL;
+ void *userdata = NULL;
+
upload_new_resource(tid, // tid
LLAssetType::AT_TEXTURE,
"Snapshot : " + pos_string,
@@ -1019,6 +1033,7 @@ void LLSnapshotLivePreview::saveTexture()
LLFloaterPerms::getEveryonePerms("Uploads"),
"Snapshot : " + pos_string,
callback, expected_upload_cost, userdata);
+#endif
gViewerWindow->playSnapshotAnimAndSound();
}
else
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 7867e1573c..3b060d8343 100755
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -34,11 +34,11 @@
#include "llgroupmgr.h"
#include "llsdutil.h"
#include "lluicolortable.h"
-#include "llhttpclient.h"
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
#include "llvoavatar.h"
#include "llworld.h"
+#include "llcorehttputil.h"
extern LLControlGroup gSavedSettings;
@@ -265,49 +265,6 @@ bool LLSpeakersDelayActionsStorage::isTimerStarted(const LLUUID& speaker_id)
}
//
-// ModerationResponder
-//
-
-class ModerationResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(ModerationResponder);
-public:
- ModerationResponder(const LLUUID& session_id)
- {
- mSessionID = session_id;
- }
-
-protected:
- virtual void httpFailure()
- {
- LL_WARNS() << dumpResponse() << LL_ENDL;
-
- if ( gIMMgr )
- {
- //403 == you're not a mod
- //should be disabled if you're not a moderator
- if ( HTTP_FORBIDDEN == getStatus() )
- {
- gIMMgr->showSessionEventError(
- "mute",
- "not_a_mod_error",
- mSessionID);
- }
- else
- {
- gIMMgr->showSessionEventError(
- "mute",
- "generic_request_error",
- mSessionID);
- }
- }
- }
-
-private:
- LLUUID mSessionID;
-};
-
-//
// LLSpeakerMgr
//
@@ -883,7 +840,8 @@ void LLIMSpeakerMgr::toggleAllowTextChat(const LLUUID& speaker_id)
//current value represents ability to type, so invert
data["params"]["mute_info"]["text"] = !speakerp->mModeratorMutedText;
- LLHTTPClient::post(url, data, new ModerationResponder(getSessionID()));
+ LLCoros::instance().launch("LLIMSpeakerMgr::moderationActionCoro",
+ boost::bind(&LLIMSpeakerMgr::moderationActionCoro, this, url, data));
}
void LLIMSpeakerMgr::moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute)
@@ -907,10 +865,50 @@ void LLIMSpeakerMgr::moderateVoiceParticipant(const LLUUID& avatar_id, bool unmu
data["params"]["mute_info"] = LLSD::emptyMap();
data["params"]["mute_info"]["voice"] = !unmute;
- LLHTTPClient::post(
- url,
- data,
- new ModerationResponder(getSessionID()));
+ LLCoros::instance().launch("LLIMSpeakerMgr::moderationActionCoro",
+ boost::bind(&LLIMSpeakerMgr::moderationActionCoro, this, url, data));
+}
+
+void LLIMSpeakerMgr::moderationActionCoro(std::string url, LLSD action)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("moderationActionCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
+
+ httpOpts->setWantHeaders(true);
+
+ LLUUID sessionId = action["session-id"];
+
+ LLSD result = httpAdapter->postAndYield(httpRequest, url, action, httpOpts);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ if (gIMMgr)
+ {
+ //403 == you're not a mod
+ //should be disabled if you're not a moderator
+ if (status == LLCore::HttpStatus(HTTP_FORBIDDEN))
+ {
+ gIMMgr->showSessionEventError(
+ "mute",
+ "not_a_mod_error",
+ sessionId);
+ }
+ else
+ {
+ gIMMgr->showSessionEventError(
+ "mute",
+ "generic_request_error",
+ sessionId);
+ }
+ }
+ return;
+ }
}
void LLIMSpeakerMgr::moderateVoiceAllParticipants( bool unmute_everyone )
@@ -949,7 +947,8 @@ void LLIMSpeakerMgr::moderateVoiceSession(const LLUUID& session_id, bool disallo
data["params"]["update_info"]["moderated_mode"] = LLSD::emptyMap();
data["params"]["update_info"]["moderated_mode"]["voice"] = disallow_voice;
- LLHTTPClient::post(url, data, new ModerationResponder(session_id));
+ LLCoros::instance().launch("LLIMSpeakerMgr::moderationActionCoro",
+ boost::bind(&LLIMSpeakerMgr::moderationActionCoro, this, url, data));
}
void LLIMSpeakerMgr::forceVoiceModeratedMode(bool should_be_muted)
diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index 0e69184125..5cff70f377 100755
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -30,6 +30,8 @@
#include "llevent.h"
#include "lleventtimer.h"
#include "llvoicechannel.h"
+#include "lleventcoro.h"
+#include "llcoros.h"
class LLSpeakerMgr;
@@ -333,6 +335,8 @@ protected:
*/
void forceVoiceModeratedMode(bool should_be_muted);
+ void moderationActionCoro(std::string url, LLSD action);
+
};
class LLActiveSpeakerMgr : public LLSpeakerMgr, public LLSingleton<LLActiveSpeakerMgr>
diff --git a/indra/newview/llsyntaxid.cpp b/indra/newview/llsyntaxid.cpp
index 802dff1ead..7f286044d6 100644
--- a/indra/newview/llsyntaxid.cpp
+++ b/indra/newview/llsyntaxid.cpp
@@ -31,70 +31,11 @@
#include "llsyntaxid.h"
#include "llagent.h"
#include "llappviewer.h"
-#include "llhttpclient.h"
#include "llsdserialize.h"
#include "llviewerregion.h"
+#include "llcorehttputil.h"
//-----------------------------------------------------------------------------
-// fetchKeywordsFileResponder
-//-----------------------------------------------------------------------------
-class fetchKeywordsFileResponder : public LLHTTPClient::Responder
-{
-public:
- fetchKeywordsFileResponder(const std::string& filespec)
- : mFileSpec(filespec)
- {
- LL_DEBUGS("SyntaxLSL") << "Instantiating with file saving to: '" << filespec << "'" << LL_ENDL;
- }
-
- /* virtual */ void httpFailure()
- {
- LL_WARNS("SyntaxLSL") << "failed to fetch syntax file [status:" << getStatus() << "]: " << getContent() << LL_ENDL;
- }
-
- /* virtual */ void httpSuccess()
- {
- // Continue only if a valid LLSD object was returned.
- const LLSD& content = getContent();
- if (content.isMap())
- {
- if (LLSyntaxIdLSL::getInstance()->isSupportedVersion(content))
- {
- LLSyntaxIdLSL::getInstance()->setKeywordsXml(content);
-
- cacheFile(content);
- LLSyntaxIdLSL::getInstance()->handleFileFetched(mFileSpec);
- }
- else
- {
- LL_WARNS("SyntaxLSL") << "Unknown or unsupported version of syntax file." << LL_ENDL;
- }
- }
- else
- {
- LL_WARNS("SyntaxLSL") << "Syntax file '" << mFileSpec << "' contains invalid LLSD." << LL_ENDL;
- }
- }
-
- void cacheFile(const LLSD& content_ref)
- {
- std::stringstream str;
- LLSDSerialize::toXML(content_ref, str);
- const std::string xml = str.str();
-
- // save the str to disk, usually to the cache.
- llofstream file(mFileSpec.c_str(), std::ios_base::out);
- file.write(xml.c_str(), str.str().size());
- file.close();
-
- LL_DEBUGS("SyntaxLSL") << "Syntax file received, saving as: '" << mFileSpec << "'" << LL_ENDL;
- }
-
-private:
- std::string mFileSpec;
-};
-
-//-----------------------------------------------------------------------------
// LLSyntaxIdLSL
//-----------------------------------------------------------------------------
const std::string SYNTAX_ID_CAPABILITY_NAME = "LSLSyntax";
@@ -166,13 +107,72 @@ bool LLSyntaxIdLSL::syntaxIdChanged()
//-----------------------------------------------------------------------------
void LLSyntaxIdLSL::fetchKeywordsFile(const std::string& filespec)
{
- mInflightFetches.push_back(filespec);
- LLHTTPClient::get(mCapabilityURL,
- new fetchKeywordsFileResponder(filespec),
- LLSD(), 30.f);
+ LLCoros::instance().launch("LLSyntaxIdLSL::fetchKeywordsFileCoro",
+ boost::bind(&LLSyntaxIdLSL::fetchKeywordsFileCoro, this, mCapabilityURL, filespec));
LL_DEBUGS("SyntaxLSL") << "LSLSyntaxId capability URL is: " << mCapabilityURL << ". Filename to use is: '" << filespec << "'." << LL_ENDL;
}
+//-----------------------------------------------------------------------------
+// fetchKeywordsFileCoro
+//-----------------------------------------------------------------------------
+void LLSyntaxIdLSL::fetchKeywordsFileCoro(std::string url, std::string fileSpec)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("genericPostCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ std::pair<std::set<std::string>::iterator, bool> insrt = mInflightFetches.insert(fileSpec);
+ if (!insrt.second)
+ {
+ LL_WARNS("SyntaxLSL") << "Already downloading keyword file called \"" << fileSpec << "\"." << LL_ENDL;
+ return;
+ }
+
+ LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ mInflightFetches.erase(fileSpec);
+
+ if (!status)
+ {
+ LL_WARNS("SyntaxLSL") << "Failed to fetch syntax file \"" << fileSpec << "\"" << LL_ENDL;
+ return;
+ }
+
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+
+ if (isSupportedVersion(result))
+ {
+ setKeywordsXml(result);
+ cacheFile(fileSpec, result);
+ loadKeywordsIntoLLSD();
+ }
+ else
+ {
+ LL_WARNS("SyntaxLSL") << "Unknown or unsupported version of syntax file." << LL_ENDL;
+ }
+
+}
+
+//-----------------------------------------------------------------------------
+// cacheFile
+//-----------------------------------------------------------------------------
+void LLSyntaxIdLSL::cacheFile(const std::string &fileSpec, const LLSD& content_ref)
+{
+ std::stringstream str;
+ LLSDSerialize::toXML(content_ref, str);
+ const std::string xml = str.str();
+
+ // save the str to disk, usually to the cache.
+ llofstream file(fileSpec.c_str(), std::ios_base::out);
+ file.write(xml.c_str(), str.str().size());
+ file.close();
+
+ LL_DEBUGS("SyntaxLSL") << "Syntax file received, saving as: '" << fileSpec << "'" << LL_ENDL;
+}
//-----------------------------------------------------------------------------
// initialize
@@ -260,8 +260,8 @@ void LLSyntaxIdLSL::loadDefaultKeywordsIntoLLSD()
// loadKeywordsFileIntoLLSD
//-----------------------------------------------------------------------------
/**
- * @brief Load xml serialised LLSD
- * @desc Opens the specified filespec and attempts to deserialise the
+ * @brief Load xml serialized LLSD
+ * @desc Opens the specified filespec and attempts to deserializes the
* contained data to the specified LLSD object. indicate success/failure with
* sLoaded/sLoadFailed members.
*/
@@ -276,7 +276,7 @@ void LLSyntaxIdLSL::loadKeywordsIntoLLSD()
{
if (isSupportedVersion(content))
{
- LL_DEBUGS("SyntaxLSL") << "Deserialised: " << mFullFileSpec << LL_ENDL;
+ LL_DEBUGS("SyntaxLSL") << "Deserialized: " << mFullFileSpec << LL_ENDL;
}
else
{
@@ -317,12 +317,6 @@ void LLSyntaxIdLSL::handleCapsReceived(const LLUUID& region_uuid)
}
}
-void LLSyntaxIdLSL::handleFileFetched(const std::string& filepath)
-{
- mInflightFetches.remove(filepath);
- loadKeywordsIntoLLSD();
-}
-
boost::signals2::connection LLSyntaxIdLSL::addSyntaxIDCallback(const syntax_id_changed_signal_t::slot_type& cb)
{
return mSyntaxIDChangedSignal.connect(cb);
diff --git a/indra/newview/llsyntaxid.h b/indra/newview/llsyntaxid.h
index 504fb0997e..0afa6dc04b 100644
--- a/indra/newview/llsyntaxid.h
+++ b/indra/newview/llsyntaxid.h
@@ -31,6 +31,8 @@
#include "llviewerprecompiledheaders.h"
#include "llsingleton.h"
+#include "lleventcoro.h"
+#include "llcoros.h"
class fetchKeywordsFileResponder;
@@ -40,7 +42,7 @@ class LLSyntaxIdLSL : public LLSingleton<LLSyntaxIdLSL>
friend class fetchKeywordsFileResponder;
private:
- std::list<std::string> mInflightFetches;
+ std::set<std::string> mInflightFetches;
typedef boost::signals2::signal<void()> syntax_id_changed_signal_t;
syntax_id_changed_signal_t mSyntaxIDChangedSignal;
boost::signals2::connection mRegionChangedCallback;
@@ -49,13 +51,15 @@ private:
bool isSupportedVersion(const LLSD& content);
void handleRegionChanged();
void handleCapsReceived(const LLUUID& region_uuid);
- void handleFileFetched(const std::string& filepath);
void setKeywordsXml(const LLSD& content) { mKeywordsXml = content; };
void buildFullFileSpec();
void fetchKeywordsFile(const std::string& filespec);
void loadDefaultKeywordsIntoLLSD();
void loadKeywordsIntoLLSD();
-
+
+ void fetchKeywordsFileCoro(std::string url, std::string fileSpec);
+ void cacheFile(const std::string &fileSpec, const LLSD& content_ref);
+
std::string mCapabilityURL;
std::string mFullFileSpec;
ELLPath mFilePath;
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index fab4203ec3..e61eeb2f4e 100755
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -35,7 +35,6 @@
#include "lltexturefetch.h"
#include "lldir.h"
-#include "llhttpclient.h"
#include "llhttpconstants.h"
#include "llimage.h"
#include "llimagej2c.h"
@@ -1558,7 +1557,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
// Will call callbackHttpGet when curl request completes
// Only server bake images use the returned headers currently, for getting retry-after field.
- LLCore::HttpOptions *options = (mFTType == FTT_SERVER_BAKE) ? mFetcher->mHttpOptionsWithHeaders: mFetcher->mHttpOptions;
+ LLCore::HttpOptions::ptr_t options = (mFTType == FTT_SERVER_BAKE) ? mFetcher->mHttpOptionsWithHeaders: mFetcher->mHttpOptions;
if (disable_range_req)
{
// 'Range:' requests may be disabled in which case all HTTP
@@ -2510,11 +2509,11 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
mTotalHTTPRequests(0),
mQAMode(qa_mode),
mHttpRequest(NULL),
- mHttpOptions(NULL),
- mHttpOptionsWithHeaders(NULL),
- mHttpHeaders(NULL),
+ mHttpOptions(),
+ mHttpOptionsWithHeaders(),
+ mHttpHeaders(),
mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
- mHttpMetricsHeaders(NULL),
+ mHttpMetricsHeaders(),
mHttpMetricsPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
mTotalCacheReadCount(0U),
mTotalCacheWriteCount(0U),
@@ -2529,13 +2528,13 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp());
mHttpRequest = new LLCore::HttpRequest;
- mHttpOptions = new LLCore::HttpOptions;
- mHttpOptionsWithHeaders = new LLCore::HttpOptions;
+ mHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
+ mHttpOptionsWithHeaders = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
mHttpOptionsWithHeaders->setWantHeaders(true);
- mHttpHeaders = new LLCore::HttpHeaders;
+ mHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders);
mHttpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_IMAGE_X_J2C);
mHttpPolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_TEXTURE);
- mHttpMetricsHeaders = new LLCore::HttpHeaders;
+ mHttpMetricsHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders);
mHttpMetricsHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML);
mHttpMetricsPolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_REPORTING);
mHttpHighWater = HTTP_NONPIPE_REQUESTS_HIGH_WATER;
@@ -2569,30 +2568,6 @@ LLTextureFetch::~LLTextureFetch()
delete req;
}
- if (mHttpOptions)
- {
- mHttpOptions->release();
- mHttpOptions = NULL;
- }
-
- if (mHttpOptionsWithHeaders)
- {
- mHttpOptionsWithHeaders->release();
- mHttpOptionsWithHeaders = NULL;
- }
-
- if (mHttpHeaders)
- {
- mHttpHeaders->release();
- mHttpHeaders = NULL;
- }
-
- if (mHttpMetricsHeaders)
- {
- mHttpMetricsHeaders->release();
- mHttpMetricsHeaders = NULL;
- }
-
mHttpWaitResource.clear();
delete mHttpRequest;
@@ -4044,7 +4019,7 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
report_priority,
mCapsURL,
sd,
- NULL,
+ LLCore::HttpOptions::ptr_t(),
fetcher->getMetricsHeaders(),
handler);
LLTextureFetch::svMetricsDataBreak = false;
@@ -4163,7 +4138,7 @@ LLTextureFetchDebugger::LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextur
mFetcher(fetcher),
mTextureCache(cache),
mImageDecodeThread(imagedecodethread),
- mHttpHeaders(NULL),
+ mHttpHeaders(),
mHttpPolicyClass(fetcher->getPolicyClass()),
mNbCurlCompleted(0),
mTempIndex(0),
@@ -4177,11 +4152,6 @@ LLTextureFetchDebugger::~LLTextureFetchDebugger()
mFetchingHistory.clear();
mStopDebug = TRUE;
tryToStopDebug();
- if (mHttpHeaders)
- {
- mHttpHeaders->release();
- mHttpHeaders = NULL;
- }
}
void LLTextureFetchDebugger::init()
@@ -4226,7 +4196,7 @@ void LLTextureFetchDebugger::init()
if (! mHttpHeaders)
{
- mHttpHeaders = new LLCore::HttpHeaders;
+ mHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders);
mHttpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_IMAGE_X_J2C);
}
}
@@ -4626,7 +4596,7 @@ S32 LLTextureFetchDebugger::fillCurlQueue()
texture_url,
0,
requestedSize,
- NULL,
+ LLCore::HttpOptions::ptr_t(),
mHttpHeaders,
this);
if (LLCORE_HTTP_HANDLE_INVALID != handle)
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index 27779a31e0..e569175e8f 100755
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -177,7 +177,7 @@ public:
// to do that to hold a reference for any length of time.
//
// Threads: T*
- LLCore::HttpHeaders * getMetricsHeaders() const { return mHttpMetricsHeaders; }
+ LLCore::HttpHeaders::ptr_t getMetricsHeaders() const { return mHttpMetricsHeaders; }
// Threads: T*
LLCore::HttpRequest::policy_t getMetricsPolicyClass() const { return mHttpMetricsPolicyClass; }
@@ -354,11 +354,11 @@ private:
// to make our HTTP requests. These replace the various
// LLCurl interfaces used in the past.
LLCore::HttpRequest * mHttpRequest; // Ttf
- LLCore::HttpOptions * mHttpOptions; // Ttf
- LLCore::HttpOptions * mHttpOptionsWithHeaders; // Ttf
- LLCore::HttpHeaders * mHttpHeaders; // Ttf
+ LLCore::HttpOptions::ptr_t mHttpOptions; // Ttf
+ LLCore::HttpOptions::ptr_t mHttpOptionsWithHeaders; // Ttf
+ LLCore::HttpHeaders::ptr_t mHttpHeaders; // Ttf
LLCore::HttpRequest::policy_t mHttpPolicyClass; // T*
- LLCore::HttpHeaders * mHttpMetricsHeaders; // Ttf
+ LLCore::HttpHeaders::ptr_t mHttpMetricsHeaders; // Ttf
LLCore::HttpRequest::policy_t mHttpMetricsPolicyClass; // T*
S32 mHttpHighWater; // Ttf
S32 mHttpLowWater; // Ttf
@@ -510,7 +510,7 @@ private:
LLTextureFetch* mFetcher;
LLTextureCache* mTextureCache;
LLImageDecodeThread* mImageDecodeThread;
- LLCore::HttpHeaders* mHttpHeaders;
+ LLCore::HttpHeaders::ptr_t mHttpHeaders;
LLCore::HttpRequest::policy_t mHttpPolicyClass;
S32 mNumFetchedTextures;
diff --git a/indra/newview/lltwitterconnect.cpp b/indra/newview/lltwitterconnect.cpp
index e983bc883f..c6a0a15759 100644
--- a/indra/newview/lltwitterconnect.cpp
+++ b/indra/newview/lltwitterconnect.cpp
@@ -32,7 +32,6 @@
#include "llagent.h"
#include "llcallingcard.h" // for LLAvatarTracker
#include "llcommandhandler.h"
-#include "llhttpclient.h"
#include "llnotificationsutil.h"
#include "llurlaction.h"
#include "llimagepng.h"
@@ -43,6 +42,7 @@
#include "llfloaterwebcontent.h"
#include "llfloaterreg.h"
+#include "llcorehttputil.h"
boost::scoped_ptr<LLEventPump> LLTwitterConnect::sStateWatcher(new LLEventStream("TwitterConnectState"));
boost::scoped_ptr<LLEventPump> LLTwitterConnect::sInfoWatcher(new LLEventStream("TwitterConnectInfo"));
@@ -67,228 +67,311 @@ void toast_user_for_twitter_success()
///////////////////////////////////////////////////////////////////////////////
//
-class LLTwitterConnectResponder : public LLHTTPClient::Responder
+void LLTwitterConnect::twitterConnectCoro(std::string requestToken, std::string oauthVerifier)
{
- LOG_CLASS(LLTwitterConnectResponder);
-public:
-
- LLTwitterConnectResponder()
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+ httpOpts->setWantHeaders(true);
+ httpOpts->setFollowRedirects(false);
+
+ LLSD body;
+ if (!requestToken.empty())
+ body["request_token"] = requestToken;
+ if (!oauthVerifier.empty())
+ body["oauth_verifier"] = oauthVerifier;
+
+ setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_IN_PROGRESS);
+
+ LLSD result = httpAdapter->putAndYield(httpRequest, getTwitterConnectURL("/connection"), body, httpOpts);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
{
- LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_IN_PROGRESS);
+ if ( status == LLCore::HttpStatus(HTTP_FOUND) )
+ {
+ std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
+ if (location.empty())
+ {
+ LL_WARNS("FlickrConnect") << "Missing Location header " << LL_ENDL;
+ }
+ else
+ {
+ openTwitterWeb(location);
+ }
+ }
+ else
+ {
+ LL_WARNS("TwitterConnect") << "Connection failed " << status.toString() << LL_ENDL;
+ setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_FAILED);
+ log_twitter_connect_error("Connect", status.getStatus(), status.toString(),
+ result.get("error_code"), result.get("error_description"));
+ }
}
-
- /* virtual */ void httpSuccess()
- {
- LL_DEBUGS("TwitterConnect") << "Connect successful. " << dumpResponse() << LL_ENDL;
- LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_CONNECTED);
- }
-
- /* virtual */ void httpFailure()
- {
- if ( HTTP_FOUND == getStatus() )
- {
- const std::string& location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
- if (location.empty())
- {
- LL_WARNS("TwitterConnect") << "Missing Location header " << dumpResponse()
- << "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
- }
- else
- {
- LLTwitterConnect::instance().openTwitterWeb(location);
- }
- }
- else
- {
- LL_WARNS("TwitterConnect") << dumpResponse() << LL_ENDL;
- LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_FAILED);
- const LLSD& content = getContent();
- log_twitter_connect_error("Connect", getStatus(), getReason(),
- content.get("error_code"), content.get("error_description"));
- }
- }
-};
+ else
+ {
+ LL_DEBUGS("TwitterConnect") << "Connect successful. " << LL_ENDL;
+ setConnectionState(LLTwitterConnect::TWITTER_CONNECTED);
+ }
+}
///////////////////////////////////////////////////////////////////////////////
//
-class LLTwitterShareResponder : public LLHTTPClient::Responder
+bool LLTwitterConnect::testShareStatus(LLSD &result)
{
- LOG_CLASS(LLTwitterShareResponder);
-public:
-
- LLTwitterShareResponder()
- {
- LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_POSTING);
- }
-
- /* virtual */ void httpSuccess()
- {
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (status)
+ return true;
+
+ if (status == LLCore::HttpStatus(HTTP_FOUND))
+ {
+ std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
+ if (location.empty())
+ {
+ LL_WARNS("TwitterConnect") << "Missing Location header " << LL_ENDL;
+ }
+ else
+ {
+ openTwitterWeb(location);
+ }
+ }
+ if (status == LLCore::HttpStatus(HTTP_NOT_FOUND))
+ {
+ LL_DEBUGS("TwitterConnect") << "Not connected. " << LL_ENDL;
+ connectToTwitter();
+ }
+ else
+ {
+ LL_WARNS("TwitterConnect") << "HTTP Status error " << status.toString() << LL_ENDL;
+ setConnectionState(LLTwitterConnect::TWITTER_POST_FAILED);
+ log_twitter_connect_error("Share", status.getStatus(), status.toString(),
+ result.get("error_code"), result.get("error_description"));
+ }
+ return false;
+}
+
+void LLTwitterConnect::twitterShareCoro(std::string route, LLSD share)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+ httpOpts->setWantHeaders(true);
+ httpOpts->setFollowRedirects(false);
+
+ setConnectionState(LLTwitterConnect::TWITTER_POSTING);
+
+ LLSD result = httpAdapter->postAndYield(httpRequest, getTwitterConnectURL(route, true), share, httpOpts);
+
+ if (testShareStatus(result))
+ {
toast_user_for_twitter_success();
- LL_DEBUGS("TwitterConnect") << "Post successful. " << dumpResponse() << LL_ENDL;
- LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_POSTED);
- }
-
- /* virtual */ void httpFailure()
- {
- if ( HTTP_FOUND == getStatus() )
- {
- const std::string& location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
- if (location.empty())
- {
- LL_WARNS("TwitterConnect") << "Missing Location header " << dumpResponse()
- << "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
- }
- else
- {
- LLTwitterConnect::instance().openTwitterWeb(location);
- }
- }
- else if ( HTTP_NOT_FOUND == getStatus() )
- {
- LLTwitterConnect::instance().connectToTwitter();
- }
- else
- {
- LL_WARNS("TwitterConnect") << dumpResponse() << LL_ENDL;
- LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_POST_FAILED);
- const LLSD& content = getContent();
- log_twitter_connect_error("Share", getStatus(), getReason(),
- content.get("error_code"), content.get("error_description"));
- }
- }
-};
+ LL_DEBUGS("TwitterConnect") << "Post successful. " << LL_ENDL;
+ setConnectionState(LLTwitterConnect::TWITTER_POSTED);
+ }
+}
+
+void LLTwitterConnect::twitterShareImageCoro(LLPointer<LLImageFormatted> image, std::string status)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+ httpOpts->setWantHeaders(true);
+ httpOpts->setFollowRedirects(false);
+
+ std::string imageFormat;
+ if (dynamic_cast<LLImagePNG*>(image.get()))
+ {
+ imageFormat = "png";
+ }
+ else if (dynamic_cast<LLImageJPEG*>(image.get()))
+ {
+ imageFormat = "jpg";
+ }
+ else
+ {
+ LL_WARNS() << "Image to upload is not a PNG or JPEG" << LL_ENDL;
+ return;
+ }
+
+ // All this code is mostly copied from LLWebProfile::post()
+ const std::string boundary = "----------------------------0123abcdefab";
+
+ std::string contentType = "multipart/form-data; boundary=" + boundary;
+ httpHeaders->append("Content-Type", contentType.c_str());
+
+ LLCore::BufferArray::ptr_t raw = LLCore::BufferArray::ptr_t(new LLCore::BufferArray()); //
+ LLCore::BufferArrayStream body(raw.get());
+
+ // *NOTE: The order seems to matter.
+ body << "--" << boundary << "\r\n"
+ << "Content-Disposition: form-data; name=\"status\"\r\n\r\n"
+ << status << "\r\n";
+
+ body << "--" << boundary << "\r\n"
+ << "Content-Disposition: form-data; name=\"image\"; filename=\"Untitled." << imageFormat << "\"\r\n"
+ << "Content-Type: image/" << imageFormat << "\r\n\r\n";
+
+ // Insert the image data.
+ // *FIX: Treating this as a string will probably screw it up ...
+ U8* image_data = image->getData();
+ for (S32 i = 0; i < image->getDataSize(); ++i)
+ {
+ body << image_data[i];
+ }
+
+ body << "\r\n--" << boundary << "--\r\n";
+
+ LLSD result = httpAdapter->postAndYield(httpRequest, getTwitterConnectURL("/share/photo", true), raw, httpOpts, httpHeaders);
+
+ if (testShareStatus(result))
+ {
+ toast_user_for_twitter_success();
+ LL_DEBUGS("TwitterConnect") << "Post successful. " << LL_ENDL;
+ setConnectionState(LLTwitterConnect::TWITTER_POSTED);
+ }
+}
///////////////////////////////////////////////////////////////////////////////
//
-class LLTwitterDisconnectResponder : public LLHTTPClient::Responder
+void LLTwitterConnect::twitterDisconnectCoro()
{
- LOG_CLASS(LLTwitterDisconnectResponder);
-public:
-
- LLTwitterDisconnectResponder()
- {
- LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_DISCONNECTING);
- }
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
- void setUserDisconnected()
- {
- // Clear data
- LLTwitterConnect::instance().clearInfo();
+ httpOpts->setFollowRedirects(false);
- //Notify state change
- LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_NOT_CONNECTED);
- }
+ setConnectionState(LLTwitterConnect::TWITTER_DISCONNECTING);
- /* virtual */ void httpSuccess()
- {
- LL_DEBUGS("TwitterConnect") << "Disconnect successful. " << dumpResponse() << LL_ENDL;
- setUserDisconnected();
- }
-
- /* virtual */ void httpFailure()
- {
- //User not found so already disconnected
- if ( HTTP_NOT_FOUND == getStatus() )
- {
- LL_DEBUGS("TwitterConnect") << "Already disconnected. " << dumpResponse() << LL_ENDL;
- setUserDisconnected();
- }
- else
- {
- LL_WARNS("TwitterConnect") << dumpResponse() << LL_ENDL;
- LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_DISCONNECT_FAILED);
- const LLSD& content = getContent();
- log_twitter_connect_error("Disconnect", getStatus(), getReason(),
- content.get("error_code"), content.get("error_description"));
- }
- }
-};
+ LLSD result = httpAdapter->deleteAndYield(httpRequest, getTwitterConnectURL("/connection"), httpOpts);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status && (status != LLCore::HttpStatus(HTTP_NOT_FOUND)))
+ {
+ LL_WARNS("TwitterConnect") << "Disconnect failed!" << LL_ENDL;
+ setConnectionState(LLTwitterConnect::TWITTER_DISCONNECT_FAILED);
+
+ log_twitter_connect_error("Disconnect", status.getStatus(), status.toString(),
+ result.get("error_code"), result.get("error_description"));
+ }
+ else
+ {
+ LL_DEBUGS("TwitterConnect") << "Disconnect successful. " << LL_ENDL;
+ clearInfo();
+ setConnectionState(LLTwitterConnect::TWITTER_NOT_CONNECTED);
+ }
+}
///////////////////////////////////////////////////////////////////////////////
//
-class LLTwitterConnectedResponder : public LLHTTPClient::Responder
+void LLTwitterConnect::twitterConnectedCoro(bool autoConnect)
{
- LOG_CLASS(LLTwitterConnectedResponder);
-public:
-
- LLTwitterConnectedResponder(bool auto_connect) : mAutoConnect(auto_connect)
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+ httpOpts->setFollowRedirects(false);
+ setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_IN_PROGRESS);
+
+ LLSD result = httpAdapter->getAndYield(httpRequest, getTwitterConnectURL("/connection", true), httpOpts);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
{
- LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_IN_PROGRESS);
+ if (status == LLCore::HttpStatus(HTTP_NOT_FOUND))
+ {
+ LL_DEBUGS("TwitterConnect") << "Not connected. " << LL_ENDL;
+ if (autoConnect)
+ {
+ connectToTwitter();
+ }
+ else
+ {
+ setConnectionState(LLTwitterConnect::TWITTER_NOT_CONNECTED);
+ }
+ }
+ else
+ {
+ LL_WARNS("TwitterConnect") << "Failed to test connection:" << status.toTerseString() << LL_ENDL;
+
+ setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_FAILED);
+ log_twitter_connect_error("Connected", status.getStatus(), status.toString(),
+ result.get("error_code"), result.get("error_description"));
+ }
+ }
+ else
+ {
+ LL_DEBUGS("TwitterConnect") << "Connect successful. " << LL_ENDL;
+ setConnectionState(LLTwitterConnect::TWITTER_CONNECTED);
}
-
- /* virtual */ void httpSuccess()
- {
- LL_DEBUGS("TwitterConnect") << "Connect successful. " << dumpResponse() << LL_ENDL;
- LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_CONNECTED);
- }
-
- /* virtual */ void httpFailure()
- {
- // show the facebook login page if not connected yet
- if ( HTTP_NOT_FOUND == getStatus() )
- {
- LL_DEBUGS("TwitterConnect") << "Not connected. " << dumpResponse() << LL_ENDL;
- if (mAutoConnect)
- {
- LLTwitterConnect::instance().connectToTwitter();
- }
- else
- {
- LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_NOT_CONNECTED);
- }
- }
- else
- {
- LL_WARNS("TwitterConnect") << dumpResponse() << LL_ENDL;
- LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_FAILED);
- const LLSD& content = getContent();
- log_twitter_connect_error("Connected", getStatus(), getReason(),
- content.get("error_code"), content.get("error_description"));
- }
- }
-
-private:
- bool mAutoConnect;
-};
+
+}
///////////////////////////////////////////////////////////////////////////////
//
-class LLTwitterInfoResponder : public LLHTTPClient::Responder
+void LLTwitterConnect::twitterInfoCoro()
{
- LOG_CLASS(LLTwitterInfoResponder);
-public:
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
- /* virtual */ void httpSuccess()
- {
- LL_INFOS("TwitterConnect") << "Twitter: Info received" << LL_ENDL;
- LL_DEBUGS("TwitterConnect") << "Getting Twitter info successful. " << dumpResponse() << LL_ENDL;
- LLTwitterConnect::instance().storeInfo(getContent());
- }
-
- /* virtual */ void httpFailure()
- {
- if ( HTTP_FOUND == getStatus() )
- {
- const std::string& location = getResponseHeader(HTTP_IN_HEADER_LOCATION);
- if (location.empty())
- {
- LL_WARNS("TwitterConnect") << "Missing Location header " << dumpResponse()
- << "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
- }
- else
- {
- LLTwitterConnect::instance().openTwitterWeb(location);
- }
- }
- else
- {
- LL_WARNS("TwitterConnect") << dumpResponse() << LL_ENDL;
- const LLSD& content = getContent();
- log_twitter_connect_error("Info", getStatus(), getReason(),
- content.get("error_code"), content.get("error_description"));
- }
- }
-};
+ httpOpts->setWantHeaders(true);
+ httpOpts->setFollowRedirects(false);
+
+ LLSD result = httpAdapter->getAndYield(httpRequest, getTwitterConnectURL("/info", true), httpOpts);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (status == LLCore::HttpStatus(HTTP_FOUND))
+ {
+ std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
+ if (location.empty())
+ {
+ LL_WARNS("TwitterConnect") << "Missing Location header " << LL_ENDL;
+ }
+ else
+ {
+ openTwitterWeb(location);
+ }
+ }
+ else if (!status)
+ {
+ LL_WARNS("TwitterConnect") << "Twitter Info failed: " << status.toString() << LL_ENDL;
+ log_twitter_connect_error("Info", status.getStatus(), status.toString(),
+ result.get("error_code"), result.get("error_description"));
+ }
+ else
+ {
+ LL_INFOS("TwitterConnect") << "Twitter: Info received" << LL_ENDL;
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ storeInfo(result);
+ }
+}
///////////////////////////////////////////////////////////////////////////////
//
@@ -341,36 +424,28 @@ std::string LLTwitterConnect::getTwitterConnectURL(const std::string& route, boo
void LLTwitterConnect::connectToTwitter(const std::string& request_token, const std::string& oauth_verifier)
{
- LLSD body;
- if (!request_token.empty())
- body["request_token"] = request_token;
- if (!oauth_verifier.empty())
- body["oauth_verifier"] = oauth_verifier;
-
- LLHTTPClient::put(getTwitterConnectURL("/connection"), body, new LLTwitterConnectResponder());
+ LLCoros::instance().launch("LLTwitterConnect::twitterConnectCoro",
+ boost::bind(&LLTwitterConnect::twitterConnectCoro, this, request_token, oauth_verifier));
}
void LLTwitterConnect::disconnectFromTwitter()
{
- LLHTTPClient::del(getTwitterConnectURL("/connection"), new LLTwitterDisconnectResponder());
+ LLCoros::instance().launch("LLTwitterConnect::twitterDisconnectCoro",
+ boost::bind(&LLTwitterConnect::twitterDisconnectCoro, this));
}
void LLTwitterConnect::checkConnectionToTwitter(bool auto_connect)
{
- const bool follow_redirects = false;
- const F32 timeout = HTTP_REQUEST_EXPIRY_SECS;
- LLHTTPClient::get(getTwitterConnectURL("/connection", true), new LLTwitterConnectedResponder(auto_connect),
- LLSD(), timeout, follow_redirects);
+ LLCoros::instance().launch("LLTwitterConnect::twitterConnectedCoro",
+ boost::bind(&LLTwitterConnect::twitterConnectedCoro, this, auto_connect));
}
void LLTwitterConnect::loadTwitterInfo()
{
if(mRefreshInfo)
{
- const bool follow_redirects = false;
- const F32 timeout = HTTP_REQUEST_EXPIRY_SECS;
- LLHTTPClient::get(getTwitterConnectURL("/info", true), new LLTwitterInfoResponder(),
- LLSD(), timeout, follow_redirects);
+ LLCoros::instance().launch("LLTwitterConnect::twitterInfoCoro",
+ boost::bind(&LLTwitterConnect::twitterInfoCoro, this));
}
}
@@ -379,62 +454,15 @@ void LLTwitterConnect::uploadPhoto(const std::string& image_url, const std::stri
LLSD body;
body["image"] = image_url;
body["status"] = status;
-
- // Note: we can use that route for different publish action. We should be able to use the same responder.
- LLHTTPClient::post(getTwitterConnectURL("/share/photo", true), body, new LLTwitterShareResponder());
+
+ LLCoros::instance().launch("LLTwitterConnect::twitterShareCoro",
+ boost::bind(&LLTwitterConnect::twitterShareCoro, this, "/share/photo", body));
}
void LLTwitterConnect::uploadPhoto(LLPointer<LLImageFormatted> image, const std::string& status)
{
- std::string imageFormat;
- if (dynamic_cast<LLImagePNG*>(image.get()))
- {
- imageFormat = "png";
- }
- else if (dynamic_cast<LLImageJPEG*>(image.get()))
- {
- imageFormat = "jpg";
- }
- else
- {
- LL_WARNS() << "Image to upload is not a PNG or JPEG" << LL_ENDL;
- return;
- }
-
- // All this code is mostly copied from LLWebProfile::post()
- const std::string boundary = "----------------------------0123abcdefab";
-
- LLSD headers;
- headers["Content-Type"] = "multipart/form-data; boundary=" + boundary;
-
- std::ostringstream body;
-
- // *NOTE: The order seems to matter.
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"status\"\r\n\r\n"
- << status << "\r\n";
-
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"image\"; filename=\"Untitled." << imageFormat << "\"\r\n"
- << "Content-Type: image/" << imageFormat << "\r\n\r\n";
-
- // Insert the image data.
- // *FIX: Treating this as a string will probably screw it up ...
- U8* image_data = image->getData();
- for (S32 i = 0; i < image->getDataSize(); ++i)
- {
- body << image_data[i];
- }
-
- body << "\r\n--" << boundary << "--\r\n";
-
- // postRaw() takes ownership of the buffer and releases it later.
- size_t size = body.str().size();
- U8 *data = new U8[size];
- memcpy(data, body.str().data(), size);
-
- // Note: we can use that route for different publish action. We should be able to use the same responder.
- LLHTTPClient::postRaw(getTwitterConnectURL("/share/photo", true), data, size, new LLTwitterShareResponder(), headers);
+ LLCoros::instance().launch("LLTwitterConnect::twitterShareImageCoro",
+ boost::bind(&LLTwitterConnect::twitterShareImageCoro, this, image, status));
}
void LLTwitterConnect::updateStatus(const std::string& status)
@@ -442,8 +470,8 @@ void LLTwitterConnect::updateStatus(const std::string& status)
LLSD body;
body["status"] = status;
- // Note: we can use that route for different publish action. We should be able to use the same responder.
- LLHTTPClient::post(getTwitterConnectURL("/share/status", true), body, new LLTwitterShareResponder());
+ LLCoros::instance().launch("LLTwitterConnect::twitterShareCoro",
+ boost::bind(&LLTwitterConnect::twitterShareCoro, this, "/share/status", body));
}
void LLTwitterConnect::storeInfo(const LLSD& info)
diff --git a/indra/newview/lltwitterconnect.h b/indra/newview/lltwitterconnect.h
index c1df13f18c..be481a17c1 100644
--- a/indra/newview/lltwitterconnect.h
+++ b/indra/newview/lltwitterconnect.h
@@ -30,6 +30,8 @@
#include "llsingleton.h"
#include "llimage.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
class LLEventPump;
@@ -94,6 +96,14 @@ private:
static boost::scoped_ptr<LLEventPump> sStateWatcher;
static boost::scoped_ptr<LLEventPump> sInfoWatcher;
static boost::scoped_ptr<LLEventPump> sContentWatcher;
+
+ bool testShareStatus(LLSD &result);
+ void twitterConnectCoro(std::string requestToken, std::string oauthVerifier);
+ void twitterDisconnectCoro();
+ void twitterConnectedCoro(bool autoConnect);
+ void twitterInfoCoro();
+ void twitterShareCoro(std::string route, LLSD share);
+ void twitterShareImageCoro(LLPointer<LLImageFormatted> image, std::string status);
};
#endif // LL_LLTWITTERCONNECT_H
diff --git a/indra/newview/lluploadfloaterobservers.cpp b/indra/newview/lluploadfloaterobservers.cpp
deleted file mode 100755
index 69b9b1f9f1..0000000000
--- a/indra/newview/lluploadfloaterobservers.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * @file lluploadfloaterobservers.cpp
- * @brief LLUploadModelPermissionsResponder definition
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, 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 "llviewerprecompiledheaders.h"
-
-#include "lluploadfloaterobservers.h"
-
-LLUploadModelPermissionsResponder::LLUploadModelPermissionsResponder(const LLHandle<LLUploadPermissionsObserver>& observer)
-:mObserverHandle(observer)
-{
-}
-
-void LLUploadModelPermissionsResponder::httpFailure()
-{
- LL_WARNS() << dumpResponse() << LL_ENDL;
-
- LLUploadPermissionsObserver* observer = mObserverHandle.get();
-
- if (observer)
- {
- observer->setPermissonsErrorStatus(getStatus(), getReason());
- }
-}
-
-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)
- {
- observer->onPermissionsReceived(content);
- }
-}
-
diff --git a/indra/newview/lluploadfloaterobservers.h b/indra/newview/lluploadfloaterobservers.h
index 4ff4a827a5..02baf8f1c0 100755
--- a/indra/newview/lluploadfloaterobservers.h
+++ b/indra/newview/lluploadfloaterobservers.h
@@ -79,18 +79,4 @@ protected:
LLRootHandle<LLWholeModelUploadObserver> mWholeModelUploadObserverHandle;
};
-
-class LLUploadModelPermissionsResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(LLUploadModelPermissionsResponder);
-public:
- LLUploadModelPermissionsResponder(const LLHandle<LLUploadPermissionsObserver>& observer);
-
-private:
- /* virtual */ void httpSuccess();
- /* virtual */ void httpFailure();
-
- LLHandle<LLUploadPermissionsObserver> mObserverHandle;
-};
-
#endif /* LL_LLUPLOADFLOATEROBSERVERS_H */
diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp
new file mode 100644
index 0000000000..426e89b9d5
--- /dev/null
+++ b/indra/newview/llviewerassetupload.cpp
@@ -0,0 +1,757 @@
+/**
+* @file llviewerassetupload.cpp
+* @author optional
+* @brief brief description of the file
+*
+* $LicenseInfo:firstyear=2011&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2011, 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 "llviewerprecompiledheaders.h"
+
+#include "linden_common.h"
+#include "llviewertexturelist.h"
+#include "llimage.h"
+#include "lltrans.h"
+#include "lluuid.h"
+#include "llvorbisencode.h"
+#include "lluploaddialog.h"
+#include "llpreviewscript.h"
+#include "llnotificationsutil.h"
+#include "lleconomy.h"
+#include "llagent.h"
+#include "llfloaterreg.h"
+#include "llstatusbar.h"
+#include "llinventorypanel.h"
+#include "llsdutil.h"
+#include "llviewerassetupload.h"
+#include "llappviewer.h"
+#include "llviewerstats.h"
+#include "llvfile.h"
+#include "llgesturemgr.h"
+#include "llpreviewnotecard.h"
+#include "llpreviewgesture.h"
+#include "llcoproceduremanager.h"
+
+void dialog_refresh_all();
+
+LLResourceUploadInfo::LLResourceUploadInfo(LLTransactionID transactId,
+ LLAssetType::EType assetType, std::string name, std::string description,
+ S32 compressionInfo, LLFolderType::EType destinationType,
+ LLInventoryType::EType inventoryType, U32 nextOWnerPerms,
+ U32 groupPerms, U32 everyonePerms, S32 expectedCost) :
+ mTransactionId(transactId),
+ mAssetType(assetType),
+ mName(name),
+ mDescription(description),
+ mCompressionInfo(compressionInfo),
+ mDestinationFolderType(destinationType),
+ mInventoryType(inventoryType),
+ mNextOwnerPerms(nextOWnerPerms),
+ mGroupPerms(groupPerms),
+ mEveryonePerms(everyonePerms),
+ mExpectedUploadCost(expectedCost),
+ mFolderId(LLUUID::null),
+ mItemId(LLUUID::null),
+ mAssetId(LLAssetID::null)
+{ }
+
+
+LLResourceUploadInfo::LLResourceUploadInfo(std::string name,
+ std::string description, S32 compressionInfo,
+ LLFolderType::EType destinationType, LLInventoryType::EType inventoryType,
+ U32 nextOWnerPerms, U32 groupPerms, U32 everyonePerms, S32 expectedCost):
+ mName(name),
+ mDescription(description),
+ mCompressionInfo(compressionInfo),
+ mDestinationFolderType(destinationType),
+ mInventoryType(inventoryType),
+ mNextOwnerPerms(nextOWnerPerms),
+ mGroupPerms(groupPerms),
+ mEveryonePerms(everyonePerms),
+ mExpectedUploadCost(expectedCost),
+ mTransactionId(),
+ mAssetType(LLAssetType::AT_NONE),
+ mFolderId(LLUUID::null),
+ mItemId(LLUUID::null),
+ mAssetId(LLAssetID::null)
+{
+ mTransactionId.generate();
+}
+
+
+LLSD LLResourceUploadInfo::prepareUpload()
+{
+ if (mAssetId.isNull())
+ generateNewAssetId();
+
+ incrementUploadStats();
+ assignDefaults();
+
+ return LLSD().with("success", LLSD::Boolean(true));
+}
+
+std::string LLResourceUploadInfo::getAssetTypeString() const
+{
+ return LLAssetType::lookup(mAssetType);
+}
+
+std::string LLResourceUploadInfo::getInventoryTypeString() const
+{
+ return LLInventoryType::lookup(mInventoryType);
+}
+
+LLSD LLResourceUploadInfo::generatePostBody()
+{
+ LLSD body;
+
+ body["folder_id"] = mFolderId;
+ body["asset_type"] = getAssetTypeString();
+ body["inventory_type"] = getInventoryTypeString();
+ body["name"] = mName;
+ body["description"] = mDescription;
+ body["next_owner_mask"] = LLSD::Integer(mNextOwnerPerms);
+ body["group_mask"] = LLSD::Integer(mGroupPerms);
+ body["everyone_mask"] = LLSD::Integer(mEveryonePerms);
+
+ return body;
+
+}
+
+void LLResourceUploadInfo::logPreparedUpload()
+{
+ LL_INFOS() << "*** Uploading: " << std::endl <<
+ "Type: " << LLAssetType::lookup(mAssetType) << std::endl <<
+ "UUID: " << mAssetId.asString() << std::endl <<
+ "Name: " << mName << std::endl <<
+ "Desc: " << mDescription << std::endl <<
+ "Expected Upload Cost: " << mExpectedUploadCost << std::endl <<
+ "Folder: " << mFolderId << std::endl <<
+ "Asset Type: " << LLAssetType::lookup(mAssetType) << LL_ENDL;
+}
+
+LLUUID LLResourceUploadInfo::finishUpload(LLSD &result)
+{
+ if (getFolderId().isNull())
+ {
+ return LLUUID::null;
+ }
+
+ U32 permsEveryone = PERM_NONE;
+ U32 permsGroup = PERM_NONE;
+ U32 permsNextOwner = PERM_ALL;
+
+ if (result.has("new_next_owner_mask"))
+ {
+ // The server provided creation perms so use them.
+ // Do not assume we got the perms we asked for in
+ // since the server may not have granted them all.
+ permsEveryone = result["new_everyone_mask"].asInteger();
+ permsGroup = result["new_group_mask"].asInteger();
+ permsNextOwner = result["new_next_owner_mask"].asInteger();
+ }
+ else
+ {
+ // The server doesn't provide creation perms
+ // so use old assumption-based perms.
+ if (getAssetTypeString() != "snapshot")
+ {
+ permsNextOwner = PERM_MOVE | PERM_TRANSFER;
+ }
+ }
+
+ LLPermissions new_perms;
+ new_perms.init(
+ gAgent.getID(),
+ gAgent.getID(),
+ LLUUID::null,
+ LLUUID::null);
+
+ new_perms.initMasks(
+ PERM_ALL,
+ PERM_ALL,
+ permsEveryone,
+ permsGroup,
+ permsNextOwner);
+
+ U32 flagsInventoryItem = 0;
+ if (result.has("inventory_flags"))
+ {
+ flagsInventoryItem = static_cast<U32>(result["inventory_flags"].asInteger());
+ if (flagsInventoryItem != 0)
+ {
+ LL_INFOS() << "inventory_item_flags " << flagsInventoryItem << LL_ENDL;
+ }
+ }
+ S32 creationDate = time_corrected();
+
+ LLUUID serverInventoryItem = result["new_inventory_item"].asUUID();
+ LLUUID serverAssetId = result["new_asset"].asUUID();
+
+ LLPointer<LLViewerInventoryItem> item = new LLViewerInventoryItem(
+ serverInventoryItem,
+ getFolderId(),
+ new_perms,
+ serverAssetId,
+ getAssetType(),
+ getInventoryType(),
+ getName(),
+ getDescription(),
+ LLSaleInfo::DEFAULT,
+ flagsInventoryItem,
+ creationDate);
+
+ gInventory.updateItem(item);
+ gInventory.notifyObservers();
+
+ return serverInventoryItem;
+}
+
+
+LLAssetID LLResourceUploadInfo::generateNewAssetId()
+{
+ if (gDisconnected)
+ {
+ LLAssetID rv;
+
+ rv.setNull();
+ return rv;
+ }
+ mAssetId = mTransactionId.makeAssetID(gAgent.getSecureSessionID());
+
+ return mAssetId;
+}
+
+void LLResourceUploadInfo::incrementUploadStats() const
+{
+ if (LLAssetType::AT_SOUND == mAssetType)
+ {
+ add(LLStatViewer::UPLOAD_SOUND, 1);
+ }
+ else if (LLAssetType::AT_TEXTURE == mAssetType)
+ {
+ add(LLStatViewer::UPLOAD_TEXTURE, 1);
+ }
+ else if (LLAssetType::AT_ANIMATION == mAssetType)
+ {
+ add(LLStatViewer::ANIMATION_UPLOADS, 1);
+ }
+}
+
+void LLResourceUploadInfo::assignDefaults()
+{
+ if (LLInventoryType::IT_NONE == mInventoryType)
+ {
+ mInventoryType = LLInventoryType::defaultForAssetType(mAssetType);
+ }
+ LLStringUtil::stripNonprintable(mName);
+ LLStringUtil::stripNonprintable(mDescription);
+
+ if (mName.empty())
+ {
+ mName = "(No Name)";
+ }
+ if (mDescription.empty())
+ {
+ mDescription = "(No Description)";
+ }
+
+ mFolderId = gInventory.findCategoryUUIDForType(
+ (mDestinationFolderType == LLFolderType::FT_NONE) ?
+ (LLFolderType::EType)mAssetType : mDestinationFolderType);
+
+}
+
+std::string LLResourceUploadInfo::getDisplayName() const
+{
+ return (mName.empty()) ? mAssetId.asString() : mName;
+};
+
+//=========================================================================
+NewFileResourceUploadInfo::NewFileResourceUploadInfo(
+ std::string fileName,
+ std::string name,
+ std::string description,
+ S32 compressionInfo,
+ LLFolderType::EType destinationType,
+ LLInventoryType::EType inventoryType,
+ U32 nextOWnerPerms,
+ U32 groupPerms,
+ U32 everyonePerms,
+ S32 expectedCost) :
+ LLResourceUploadInfo(name, description, compressionInfo,
+ destinationType, inventoryType,
+ nextOWnerPerms, groupPerms, everyonePerms, expectedCost),
+ mFileName(fileName)
+{
+}
+
+
+
+LLSD NewFileResourceUploadInfo::prepareUpload()
+{
+ if (getAssetId().isNull())
+ generateNewAssetId();
+
+ LLSD result = exportTempFile();
+ if (result.has("error"))
+ return result;
+
+ return LLResourceUploadInfo::prepareUpload();
+}
+
+LLSD NewFileResourceUploadInfo::exportTempFile()
+{
+ std::string filename = gDirUtilp->getTempFilename();
+
+ std::string exten = gDirUtilp->getExtension(getFileName());
+ U32 codec = LLImageBase::getCodecFromExtension(exten);
+
+ LLAssetType::EType assetType = LLAssetType::AT_NONE;
+ std::string errorMessage;
+ std::string errorLabel;
+
+ bool error = false;
+
+ if (exten.empty())
+ {
+ std::string shortName = gDirUtilp->getBaseFileName(filename);
+
+ // No extension
+ errorMessage = llformat(
+ "No file extension for the file: '%s'\nPlease make sure the file has a correct file extension",
+ shortName.c_str());
+ errorLabel = "NoFileExtension";
+ error = true;
+ }
+ else if (codec != IMG_CODEC_INVALID)
+ {
+ // It's an image file, the upload procedure is the same for all
+ assetType = LLAssetType::AT_TEXTURE;
+ if (!LLViewerTextureList::createUploadFile(getFileName(), filename, codec))
+ {
+ errorMessage = llformat("Problem with file %s:\n\n%s\n",
+ getFileName().c_str(), LLImage::getLastError().c_str());
+ errorLabel = "ProblemWithFile";
+ error = true;
+ }
+ }
+ else if (exten == "wav")
+ {
+ assetType = LLAssetType::AT_SOUND; // tag it as audio
+ S32 encodeResult = 0;
+
+ LL_INFOS() << "Attempting to encode wav as an ogg file" << LL_ENDL;
+
+ encodeResult = encode_vorbis_file(getFileName(), filename);
+
+ if (LLVORBISENC_NOERR != encodeResult)
+ {
+ switch (encodeResult)
+ {
+ case LLVORBISENC_DEST_OPEN_ERR:
+ errorMessage = llformat("Couldn't open temporary compressed sound file for writing: %s\n", filename.c_str());
+ errorLabel = "CannotOpenTemporarySoundFile";
+ break;
+
+ default:
+ errorMessage = llformat("Unknown vorbis encode failure on: %s\n", getFileName().c_str());
+ errorLabel = "UnknownVorbisEncodeFailure";
+ break;
+ }
+ error = true;
+ }
+ }
+ else if (exten == "bvh")
+ {
+ errorMessage = llformat("We do not currently support bulk upload of animation files\n");
+ errorLabel = "DoNotSupportBulkAnimationUpload";
+ error = true;
+ }
+ else if (exten == "anim")
+ {
+ assetType = LLAssetType::AT_ANIMATION;
+ filename = getFileName();
+ }
+ else
+ {
+ // Unknown extension
+ errorMessage = llformat(LLTrans::getString("UnknownFileExtension").c_str(), exten.c_str());
+ errorLabel = "ErrorMessage";
+ error = TRUE;;
+ }
+
+ if (error)
+ {
+ LLSD errorResult(LLSD::emptyMap());
+
+ errorResult["error"] = LLSD::Binary(true);
+ errorResult["message"] = errorMessage;
+ errorResult["label"] = errorLabel;
+ return errorResult;
+ }
+
+ setAssetType(assetType);
+
+ // copy this file into the vfs for upload
+ S32 file_size;
+ LLAPRFile infile;
+ infile.open(filename, LL_APR_RB, NULL, &file_size);
+ if (infile.getFileHandle())
+ {
+ LLVFile file(gVFS, getAssetId(), assetType, LLVFile::WRITE);
+
+ file.setMaxSize(file_size);
+
+ const S32 buf_size = 65536;
+ U8 copy_buf[buf_size];
+ while ((file_size = infile.read(copy_buf, buf_size)))
+ {
+ file.write(copy_buf, file_size);
+ }
+ }
+ else
+ {
+ errorMessage = llformat("Unable to access output file: %s", filename.c_str());
+ LLSD errorResult(LLSD::emptyMap());
+
+ errorResult["error"] = LLSD::Binary(true);
+ errorResult["message"] = errorMessage;
+ return errorResult;
+ }
+
+ return LLSD();
+
+}
+
+//=========================================================================
+LLBufferedAssetUploadInfo::LLBufferedAssetUploadInfo(LLUUID itemId, LLAssetType::EType assetType, std::string buffer, invnUploadFinish_f finish) :
+ LLResourceUploadInfo(std::string(), std::string(), 0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
+ 0, 0, 0, 0),
+ mTaskUpload(false),
+ mTaskId(LLUUID::null),
+ mContents(buffer),
+ mInvnFinishFn(finish),
+ mTaskFinishFn(NULL),
+ mStoredToVFS(false)
+{
+ setItemId(itemId);
+ setAssetType(assetType);
+
+}
+
+LLBufferedAssetUploadInfo::LLBufferedAssetUploadInfo(LLUUID taskId, LLUUID itemId, LLAssetType::EType assetType, std::string buffer, taskUploadFinish_f finish) :
+ LLResourceUploadInfo(std::string(), std::string(), 0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
+ 0, 0, 0, 0),
+ mTaskUpload(true),
+ mTaskId(taskId),
+ mContents(buffer),
+ mInvnFinishFn(NULL),
+ mTaskFinishFn(finish),
+ mStoredToVFS(false)
+{
+ setItemId(itemId);
+ setAssetType(assetType);
+}
+
+
+LLSD LLBufferedAssetUploadInfo::prepareUpload()
+{
+ if (getAssetId().isNull())
+ generateNewAssetId();
+
+ LLVFile file(gVFS, getAssetId(), getAssetType(), LLVFile::APPEND);
+
+ S32 size = mContents.length() + 1;
+ file.setMaxSize(size);
+ file.write((U8*)mContents.c_str(), size);
+
+ mStoredToVFS = true;
+
+
+ return LLSD().with("success", LLSD::Boolean(true));
+}
+
+LLSD LLBufferedAssetUploadInfo::generatePostBody()
+{
+ LLSD body;
+
+ if (!getTaskId().isNull())
+ {
+ body["task_id"] = getTaskId();
+ }
+ body["item_id"] = getItemId();
+
+ return body;
+}
+
+LLUUID LLBufferedAssetUploadInfo::finishUpload(LLSD &result)
+{
+ LLUUID newAssetId = result["new_asset"].asUUID();
+ LLUUID itemId = getItemId();
+
+ if (mStoredToVFS)
+ {
+ LLAssetType::EType assetType(getAssetType());
+ gVFS->renameFile(getAssetId(), assetType, newAssetId, assetType);
+ }
+
+ if (mTaskUpload)
+ {
+ LLUUID taskId = getTaskId();
+
+ dialog_refresh_all();
+
+ if (mTaskFinishFn)
+ {
+ mTaskFinishFn(itemId, taskId, newAssetId, result);
+ }
+ }
+ else
+ {
+ LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(itemId);
+ if(!item)
+ {
+ LL_WARNS() << "Inventory item for " << getDisplayName() << " is no longer in agent inventory." << LL_ENDL;
+ return newAssetId;
+ }
+
+ // Update viewer inventory item
+ LLPointer<LLViewerInventoryItem> newItem = new LLViewerInventoryItem(item);
+ newItem->setAssetUUID(newAssetId);
+
+ gInventory.updateItem(newItem);
+
+ LL_INFOS() << "Inventory item " << item->getName() << " saved into " << newAssetId.asString() << LL_ENDL;
+
+ if (mInvnFinishFn)
+ {
+ mInvnFinishFn(itemId, newAssetId, newItem->getUUID(), result);
+ }
+ gInventory.notifyObservers();
+ }
+
+ return newAssetId;
+}
+
+//=========================================================================
+
+LLScriptAssetUpload::LLScriptAssetUpload(LLUUID itemId, std::string buffer, invnUploadFinish_f finish):
+ LLBufferedAssetUploadInfo(itemId, LLAssetType::AT_LSL_TEXT, buffer, finish)
+{
+}
+
+// LLScriptAssetUpload::LLScriptAssetUpload(LLUUID taskId, LLUUID itemId, LLAssetType::EType assetType, std::string buffer, taskUploadFinish_f finish):
+// LLBufferedAssetUploadInfo()
+// {
+// }
+
+LLSD LLScriptAssetUpload::generatePostBody()
+{
+ LLSD body;
+
+ if (getTaskId().isNull())
+ {
+ body["item_id"] = getItemId();
+ body["target"] = "lsl2";
+ }
+
+ return body;
+}
+
+//=========================================================================
+/*static*/
+LLUUID LLViewerAssetUpload::EnqueueInventoryUpload(const std::string &url, const LLResourceUploadInfo::ptr_t &uploadInfo)
+{
+ std::string procName("LLViewerAssetUpload::AssetInventoryUploadCoproc(");
+
+ LLUUID queueId = LLCoprocedureManager::getInstance()->enqueueCoprocedure(procName + LLAssetType::lookup(uploadInfo->getAssetType()) + ")",
+ boost::bind(&LLViewerAssetUpload::AssetInventoryUploadCoproc, _1, _2, url, uploadInfo));
+
+ return queueId;
+}
+
+//=========================================================================
+/*static*/
+void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter,
+ const LLUUID &id, std::string url, LLResourceUploadInfo::ptr_t uploadInfo)
+{
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLSD result = uploadInfo->prepareUpload();
+ uploadInfo->logPreparedUpload();
+
+ if (result.has("error"))
+ {
+ HandleUploadError(LLCore::HttpStatus(499), result, uploadInfo);
+ return;
+ }
+
+ //self.yield();
+
+ if (uploadInfo->showUploadDialog())
+ {
+ std::string uploadMessage = "Uploading...\n\n";
+ uploadMessage.append(uploadInfo->getDisplayName());
+ LLUploadDialog::modalUploadDialog(uploadMessage);
+ }
+
+ LLSD body = uploadInfo->generatePostBody();
+
+ result = httpAdapter->postAndYield(httpRequest, url, body);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if ((!status) || (result.has("error")))
+ {
+ HandleUploadError(status, result, uploadInfo);
+ if (uploadInfo->showUploadDialog())
+ LLUploadDialog::modalUploadFinished();
+ return;
+ }
+
+ std::string uploader = result["uploader"].asString();
+
+ result = httpAdapter->postFileAndYield(httpRequest, uploader, uploadInfo->getAssetId(), uploadInfo->getAssetType());
+ httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ HandleUploadError(status, result, uploadInfo);
+ if (uploadInfo->showUploadDialog())
+ LLUploadDialog::modalUploadFinished();
+ return;
+ }
+
+ S32 uploadPrice = 0;
+
+ // Update L$ and ownership credit information
+ // since it probably changed on the server
+ if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE ||
+ uploadInfo->getAssetType() == LLAssetType::AT_SOUND ||
+ uploadInfo->getAssetType() == LLAssetType::AT_ANIMATION ||
+ uploadInfo->getAssetType() == LLAssetType::AT_MESH)
+ {
+ uploadPrice = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
+ }
+
+ bool success = false;
+
+ if (uploadPrice > 0)
+ {
+ // this upload costed us L$, update our balance
+ // and display something saying that it cost L$
+ LLStatusBar::sendMoneyBalanceRequest();
+
+ LLSD args;
+ args["AMOUNT"] = llformat("%d", uploadPrice);
+ LLNotificationsUtil::add("UploadPayment", args);
+ }
+
+ LLUUID serverInventoryItem = uploadInfo->finishUpload(result);
+
+ if (serverInventoryItem.notNull())
+ {
+ success = true;
+
+ // Show the preview panel for textures and sounds to let
+ // user know that the image (or snapshot) arrived intact.
+ LLInventoryPanel* panel = LLInventoryPanel::getActiveInventoryPanel();
+ if (panel)
+ {
+ LLFocusableElement* focus = gFocusMgr.getKeyboardFocus();
+ panel->setSelection(serverInventoryItem, TAKE_FOCUS_NO);
+
+ // restore keyboard focus
+ gFocusMgr.setKeyboardFocus(focus);
+ }
+ }
+ else
+ {
+ LL_WARNS() << "Can't find a folder to put it in" << LL_ENDL;
+ }
+
+ // remove the "Uploading..." message
+ if (uploadInfo->showUploadDialog())
+ LLUploadDialog::modalUploadFinished();
+
+ // Let the Snapshot floater know we have finished uploading a snapshot to inventory.
+ LLFloater* floater_snapshot = LLFloaterReg::findInstance("snapshot");
+ if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_snapshot)
+ {
+ floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", success).with("msg", "inventory")));
+ }
+}
+
+//=========================================================================
+/*static*/
+void LLViewerAssetUpload::HandleUploadError(LLCore::HttpStatus status, LLSD &result, LLResourceUploadInfo::ptr_t &uploadInfo)
+{
+ std::string reason;
+ std::string label("CannotUploadReason");
+
+ LL_WARNS() << ll_pretty_print_sd(result) << LL_ENDL;
+
+ if (result.has("label"))
+ {
+ label = result["label"].asString();
+ }
+
+ if (result.has("message"))
+ {
+ reason = result["message"].asString();
+ }
+ else
+ {
+ if (status.getType() == 499)
+ {
+ reason = "The server is experiencing unexpected difficulties.";
+ }
+ else
+ {
+ reason = "Error in upload request. Please visit "
+ "http://secondlife.com/support for help fixing this problem.";
+ }
+ }
+
+ LLSD args;
+ args["FILE"] = uploadInfo->getDisplayName();
+ args["REASON"] = reason;
+
+ LLNotificationsUtil::add(label, args);
+
+ // unfreeze script preview
+ if (uploadInfo->getAssetType() == LLAssetType::AT_LSL_TEXT)
+ {
+ LLPreviewLSL* preview = LLFloaterReg::findTypedInstance<LLPreviewLSL>("preview_script",
+ uploadInfo->getItemId());
+ if (preview)
+ {
+ LLSD errors;
+ errors.append(LLTrans::getString("UploadFailed") + reason);
+ preview->callbackLSLCompileFailed(errors);
+ }
+ }
+
+}
+
diff --git a/indra/newview/llviewerassetupload.h b/indra/newview/llviewerassetupload.h
new file mode 100644
index 0000000000..fa8247cb64
--- /dev/null
+++ b/indra/newview/llviewerassetupload.h
@@ -0,0 +1,208 @@
+/**
+* @file llviewerassetupload.h
+* @author optional
+* @brief brief description of the file
+*
+* $LicenseInfo:firstyear=2011&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2011, 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_VIEWER_ASSET_UPLOAD_H
+#define LL_VIEWER_ASSET_UPLOAD_H
+
+#include "llfoldertype.h"
+#include "llassettype.h"
+#include "llinventorytype.h"
+#include "lleventcoro.h"
+#include "llcoros.h"
+#include "llcorehttputil.h"
+
+//=========================================================================
+class LLResourceUploadInfo
+{
+public:
+ typedef boost::shared_ptr<LLResourceUploadInfo> ptr_t;
+
+ LLResourceUploadInfo(
+ LLTransactionID transactId,
+ LLAssetType::EType assetType,
+ std::string name,
+ std::string description,
+ S32 compressionInfo,
+ LLFolderType::EType destinationType,
+ LLInventoryType::EType inventoryType,
+ U32 nextOWnerPerms,
+ U32 groupPerms,
+ U32 everyonePerms,
+ S32 expectedCost);
+
+ virtual ~LLResourceUploadInfo()
+ { }
+
+ virtual LLSD prepareUpload();
+ virtual LLSD generatePostBody();
+ virtual void logPreparedUpload();
+ virtual LLUUID finishUpload(LLSD &result);
+
+ LLTransactionID getTransactionId() const { return mTransactionId; }
+ LLAssetType::EType getAssetType() const { return mAssetType; }
+ std::string getAssetTypeString() const;
+ std::string getName() const { return mName; };
+ std::string getDescription() const { return mDescription; };
+ S32 getCompressionInfo() const { return mCompressionInfo; };
+ LLFolderType::EType getDestinationFolderType() const { return mDestinationFolderType; };
+ LLInventoryType::EType getInventoryType() const { return mInventoryType; };
+ std::string getInventoryTypeString() const;
+ U32 getNextOwnerPerms() const { return mNextOwnerPerms; };
+ U32 getGroupPerms() const { return mGroupPerms; };
+ U32 getEveryonePerms() const { return mEveryonePerms; };
+ S32 getExpectedUploadCost() const { return mExpectedUploadCost; };
+
+ virtual bool showUploadDialog() const { return true; }
+
+ virtual std::string getDisplayName() const;
+
+ LLUUID getFolderId() const { return mFolderId; }
+ LLUUID getItemId() const { return mItemId; }
+ LLAssetID getAssetId() const { return mAssetId; }
+
+protected:
+ LLResourceUploadInfo(
+ std::string name,
+ std::string description,
+ S32 compressionInfo,
+ LLFolderType::EType destinationType,
+ LLInventoryType::EType inventoryType,
+ U32 nextOWnerPerms,
+ U32 groupPerms,
+ U32 everyonePerms,
+ S32 expectedCost);
+
+ void setTransactionId(LLTransactionID tid) { mTransactionId = tid; }
+ void setAssetType(LLAssetType::EType assetType) { mAssetType = assetType; }
+ void setItemId(LLUUID itemId) { mItemId = itemId; }
+
+ LLAssetID generateNewAssetId();
+ void incrementUploadStats() const;
+ virtual void assignDefaults();
+
+private:
+ LLTransactionID mTransactionId;
+ LLAssetType::EType mAssetType;
+ std::string mName;
+ std::string mDescription;
+ S32 mCompressionInfo;
+ LLFolderType::EType mDestinationFolderType;
+ LLInventoryType::EType mInventoryType;
+ U32 mNextOwnerPerms;
+ U32 mGroupPerms;
+ U32 mEveryonePerms;
+ S32 mExpectedUploadCost;
+
+ LLUUID mFolderId;
+ LLUUID mItemId;
+ LLAssetID mAssetId;
+};
+
+//-------------------------------------------------------------------------
+class NewFileResourceUploadInfo : public LLResourceUploadInfo
+{
+public:
+ NewFileResourceUploadInfo(
+ std::string fileName,
+ std::string name,
+ std::string description,
+ S32 compressionInfo,
+ LLFolderType::EType destinationType,
+ LLInventoryType::EType inventoryType,
+ U32 nextOWnerPerms,
+ U32 groupPerms,
+ U32 everyonePerms,
+ S32 expectedCost);
+
+ virtual LLSD prepareUpload();
+
+ std::string getFileName() const { return mFileName; };
+
+protected:
+
+ virtual LLSD exportTempFile();
+
+private:
+ std::string mFileName;
+
+};
+
+//-------------------------------------------------------------------------
+class LLBufferedAssetUploadInfo : public LLResourceUploadInfo
+{
+public:
+ typedef boost::function<void(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD response)> invnUploadFinish_f;
+ typedef boost::function<void(LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response)> taskUploadFinish_f;
+
+ LLBufferedAssetUploadInfo(LLUUID itemId, LLAssetType::EType assetType, std::string buffer, invnUploadFinish_f finish);
+ LLBufferedAssetUploadInfo(LLUUID taskId, LLUUID itemId, LLAssetType::EType assetType, std::string buffer, taskUploadFinish_f finish);
+
+ virtual LLSD prepareUpload();
+ virtual LLSD generatePostBody();
+ virtual LLUUID finishUpload(LLSD &result);
+
+ LLUUID getTaskId() const { return mTaskId; }
+ const std::string & getContents() const { return mContents; }
+
+ virtual bool showUploadDialog() const { return false; }
+
+protected:
+
+
+private:
+ bool mTaskUpload;
+ LLUUID mTaskId;
+ std::string mContents;
+ invnUploadFinish_f mInvnFinishFn;
+ taskUploadFinish_f mTaskFinishFn;
+ bool mStoredToVFS;
+};
+
+//-------------------------------------------------------------------------
+class LLScriptAssetUpload : public LLBufferedAssetUploadInfo
+{
+public:
+ LLScriptAssetUpload(LLUUID itemId, std::string buffer, invnUploadFinish_f finish);
+ LLScriptAssetUpload(LLUUID taskId, LLUUID itemId, LLAssetType::EType assetType, std::string buffer, taskUploadFinish_f finish);
+
+ virtual LLSD generatePostBody();
+
+};
+
+//=========================================================================
+class LLViewerAssetUpload
+{
+public:
+ static LLUUID EnqueueInventoryUpload(const std::string &url, const LLResourceUploadInfo::ptr_t &uploadInfo);
+
+ static void AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter, const LLUUID &id, std::string url, LLResourceUploadInfo::ptr_t uploadInfo);
+
+private:
+ static void HandleUploadError(LLCore::HttpStatus status, LLSD &result, LLResourceUploadInfo::ptr_t &uploadInfo);
+};
+
+#endif // !VIEWER_ASSET_UPLOAD_H
diff --git a/indra/newview/llviewerdisplayname.cpp b/indra/newview/llviewerdisplayname.cpp
deleted file mode 100755
index e390e8776d..0000000000
--- a/indra/newview/llviewerdisplayname.cpp
+++ /dev/null
@@ -1,211 +0,0 @@
-/**
- * @file llviewerdisplayname.cpp
- * @brief Wrapper for display name functionality
- *
- * $LicenseInfo:firstyear=2010&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 "llviewerprecompiledheaders.h"
-
-#include "llviewerdisplayname.h"
-
-// viewer includes
-#include "llagent.h"
-#include "llviewerregion.h"
-#include "llvoavatar.h"
-
-// library includes
-#include "llavatarnamecache.h"
-#include "llhttpclient.h"
-#include "llhttpnode.h"
-#include "llnotificationsutil.h"
-#include "llui.h" // getLanguage()
-
-namespace LLViewerDisplayName
-{
- // Fired when viewer receives server response to display name change
- set_name_signal_t sSetDisplayNameSignal;
-
- // Fired when there is a change in the agent's name
- name_changed_signal_t sNameChangedSignal;
-
- void addNameChangedCallback(const name_changed_signal_t::slot_type& cb)
- {
- sNameChangedSignal.connect(cb);
- }
-
- void doNothing() { }
-}
-
-class LLSetDisplayNameResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(LLSetDisplayNameResponder);
-private:
- // only care about errors
- /*virtual*/ void httpFailure()
- {
- LL_WARNS() << dumpResponse() << LL_ENDL;
- LLViewerDisplayName::sSetDisplayNameSignal(false, "", LLSD());
- LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots();
- }
-};
-
-void LLViewerDisplayName::set(const std::string& display_name, const set_name_slot_t& slot)
-{
- // TODO: simple validation here
-
- LLViewerRegion* region = gAgent.getRegion();
- llassert(region);
- std::string cap_url = region->getCapability("SetDisplayName");
- if (cap_url.empty())
- {
- // this server does not support display names, report error
- slot(false, "unsupported", LLSD());
- return;
- }
-
- // People API can return localized error messages. Indicate our
- // language preference via header.
- LLSD headers;
- headers[HTTP_OUT_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
- // to request a change, so we can use direct lookup without callback.
- LLAvatarName av_name;
- if (!LLAvatarNameCache::get( gAgent.getID(), &av_name))
- {
- slot(false, "name unavailable", LLSD());
- return;
- }
-
- // People API expects array of [ "old value", "new value" ]
- LLSD change_array = LLSD::emptyArray();
- change_array.append(av_name.getDisplayName());
- change_array.append(display_name);
-
- LL_INFOS() << "Set name POST to " << cap_url << LL_ENDL;
-
- // Record our caller for when the server sends back a reply
- sSetDisplayNameSignal.connect(slot);
-
- // POST the requested change. The sim will not send a response back to
- // this request directly, rather it will send a separate message after it
- // communicates with the back-end.
- LLSD body;
- body["display_name"] = change_array;
- LLHTTPClient::post(cap_url, body, new LLSetDisplayNameResponder, headers);
-}
-
-class LLSetDisplayNameReply : public LLHTTPNode
-{
- LOG_CLASS(LLSetDisplayNameReply);
-public:
- /*virtual*/ void post(
- LLHTTPNode::ResponsePtr response,
- const LLSD& context,
- const LLSD& input) const
- {
- LLSD body = input["body"];
-
- S32 status = body["status"].asInteger();
- bool success = (status == HTTP_OK);
- std::string reason = body["reason"].asString();
- LLSD content = body["content"];
-
- LL_INFOS() << "status " << status << " reason " << reason << LL_ENDL;
-
- // 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 == HTTP_CONFLICT)
- {
- LLUUID agent_id = gAgent.getID();
- // Flush stale data
- LLAvatarNameCache::erase( agent_id );
- // Queue request for new data: nothing to do on callback though...
- // Note: no need to disconnect the callback as it never gets out of scope
- LLAvatarNameCache::get(agent_id, boost::bind(&LLViewerDisplayName::doNothing));
- // Kill name tag, as it is wrong
- LLVOAvatar::invalidateNameTag( agent_id );
- }
-
- // inform caller of result
- LLViewerDisplayName::sSetDisplayNameSignal(success, reason, content);
- LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots();
- }
-};
-
-
-class LLDisplayNameUpdate : public LLHTTPNode
-{
- /*virtual*/ void post(
- LLHTTPNode::ResponsePtr response,
- const LLSD& context,
- const LLSD& input) const
- {
- LLSD body = input["body"];
- LLUUID agent_id = body["agent_id"];
- std::string old_display_name = body["old_display_name"];
- // By convention this record is called "agent" in the People API
- LLSD name_data = body["agent"];
-
- // Inject the new name data into cache
- LLAvatarName av_name;
- av_name.fromLLSD( name_data );
-
- LL_INFOS() << "name-update now " << LLDate::now()
- << " next_update " << LLDate(av_name.mNextUpdate)
- << LL_ENDL;
-
- // Name expiration time may be provided in headers, or we may use a
- // default value
- // *TODO: get actual headers out of ResponsePtr
- //LLSD headers = response->mHeaders;
- LLSD headers;
- av_name.mExpires =
- LLAvatarNameCache::nameExpirationFromHeaders(headers);
-
- LLAvatarNameCache::insert(agent_id, av_name);
-
- // force name tag to update
- LLVOAvatar::invalidateNameTag(agent_id);
-
- LLSD args;
- args["OLD_NAME"] = old_display_name;
- args["SLID"] = av_name.getUserName();
- args["NEW_NAME"] = av_name.getDisplayName();
- LLNotificationsUtil::add("DisplayNameUpdate", args);
- if (agent_id == gAgent.getID())
- {
- LLViewerDisplayName::sNameChangedSignal();
- }
- }
-};
-
-LLHTTPRegistration<LLSetDisplayNameReply>
- gHTTPRegistrationMessageSetDisplayNameReply(
- "/message/SetDisplayNameReply");
-
-LLHTTPRegistration<LLDisplayNameUpdate>
- gHTTPRegistrationMessageDisplayNameUpdate(
- "/message/DisplayNameUpdate");
diff --git a/indra/newview/llviewerdisplayname.h b/indra/newview/llviewerdisplayname.h
deleted file mode 100755
index 16d59ae43b..0000000000
--- a/indra/newview/llviewerdisplayname.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * @file llviewerdisplayname.h
- * @brief Wrapper for display name functionality
- *
- * $LicenseInfo:firstyear=2010&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 LLVIEWERDISPLAYNAME_H
-#define LLVIEWERDISPLAYNAME_H
-
-#include <boost/signals2.hpp>
-
-class LLSD;
-class LLUUID;
-
-namespace LLViewerDisplayName
-{
- typedef boost::signals2::signal<
- void (bool success, const std::string& reason, const LLSD& content)>
- set_name_signal_t;
- typedef set_name_signal_t::slot_type set_name_slot_t;
-
- typedef boost::signals2::signal<void (void)> name_changed_signal_t;
- typedef name_changed_signal_t::slot_type name_changed_slot_t;
-
- // Sends an update to the server to change a display name
- // and call back when done. May not succeed due to service
- // unavailable or name not available.
- void set(const std::string& display_name, const set_name_slot_t& slot);
-
- void addNameChangedCallback(const name_changed_signal_t::slot_type& cb);
-}
-
-#endif // LLVIEWERDISPLAYNAME_H
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 1dad9dd506..8627c848b5 100755
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -56,7 +56,6 @@
#include "llfloaterconversationpreview.h"
#include "llfloaterdeleteenvpreset.h"
#include "llfloaterdestinations.h"
-#include "llfloaterdisplayname.h"
#include "llfloatereditdaycycle.h"
#include "llfloatereditsky.h"
#include "llfloatereditwater.h"
@@ -244,7 +243,6 @@ void LLViewerFloaterReg::registerFloaters()
LLInspectRemoteObjectUtil::registerFloater();
LLFloaterVoiceVolumeUtil::registerFloater();
LLNotificationsUI::registerFloater();
- LLFloaterDisplayNameUtil::registerFloater();
LLFloaterReg::add("lagmeter", "floater_lagmeter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLagMeter>);
LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLandHoldings>);
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index a8634d1e93..f6db5d5d77 100755
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -1750,27 +1750,20 @@ void copy_inventory_from_notecard(const LLUUID& destination_id,
return;
}
- // check capability to prevent a crash while LL_ERRS in LLCapabilityListener::capListener. See EXT-8459.
- std::string url = viewer_region->getCapability("CopyInventoryFromNotecard");
- if (url.empty())
- {
- LL_WARNS(LOG_NOTECARD) << "There is no 'CopyInventoryFromNotecard' capability"
- << " for region: " << viewer_region->getName()
- << LL_ENDL;
- return;
- }
-
- LLSD request, body;
+ LLSD body;
body["notecard-id"] = notecard_inv_id;
body["object-id"] = object_id;
body["item-id"] = src->getUUID();
body["folder-id"] = destination_id;
body["callback-id"] = (LLSD::Integer)callback_id;
- request["message"] = "CopyInventoryFromNotecard";
- request["payload"] = body;
-
- viewer_region->getCapAPI().post(request);
+ /// *TODO: RIDER: This posts the request under the agents policy.
+ /// When I convert the inventory over this call should be moved under that
+ /// policy as well.
+ if (!gAgent.requestPostCapability("CopyInventoryFromNotecard", body))
+ {
+ LL_WARNS() << "SIM does not have the capability to copy from notecard." << LL_ENDL;
+ }
}
void create_new_item(const std::string& name,
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 3eae0f8d86..f332a4e98e 100755
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -69,6 +69,7 @@
#include "llwebprofile.h"
#include "llwindow.h"
#include "llvieweraudio.h"
+#include "llcorehttputil.h"
#include "llfloaterwebcontent.h" // for handling window close requests and geometry change requests in media browser windows.
@@ -152,190 +153,6 @@ LLViewerMediaObserver::~LLViewerMediaObserver()
}
-// Move this to its own file.
-// helper class that tries to download a URL from a web site and calls a method
-// on the Panel Land Media and to discover the MIME type
-class LLMimeDiscoveryResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(LLMimeDiscoveryResponder);
-public:
- LLMimeDiscoveryResponder( viewer_media_t media_impl)
- : mMediaImpl(media_impl),
- mInitialized(false)
- {
- if(mMediaImpl->mMimeTypeProbe != NULL)
- {
- LL_ERRS() << "impl already has an outstanding responder" << LL_ENDL;
- }
-
- mMediaImpl->mMimeTypeProbe = this;
- }
-
- ~LLMimeDiscoveryResponder()
- {
- disconnectOwner();
- }
-
-private:
- /* virtual */ void httpCompleted()
- {
- if (!isGoodStatus())
- {
- LL_WARNS() << dumpResponse()
- << " [headers:" << getResponseHeaders() << "]" << LL_ENDL;
- }
- const std::string& media_type = getResponseHeader(HTTP_IN_HEADER_CONTENT_TYPE);
- std::string::size_type idx1 = media_type.find_first_of(";");
- std::string mime_type = media_type.substr(0, idx1);
-
- LL_DEBUGS() << "status is " << getStatus() << ", media type \"" << media_type << "\"" << LL_ENDL;
-
- // 2xx status codes indicate success.
- // Most 4xx status codes are successful enough for our purposes.
- // 499 is the error code for host not found, timeout, etc.
- // 500 means "Internal Server error" but we decided it's okay to
- // accept this and go past it in the MIME type probe
- // 302 means the resource can be found temporarily in a different place - added this for join.secondlife.com
- // 499 is a code specifc to join.secondlife.com apparently safe to ignore
-// if( ((status >= 200) && (status < 300)) ||
-// ((status >= 400) && (status < 499)) ||
-// (status == 500) ||
-// (status == 302) ||
-// (status == 499)
-// )
- // 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)
- {
- // 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 = HTTP_CONTENT_TEXT_HTML;
- }
- }
- //else
- //{
- // LL_WARNS() << "responder failed with status " << dumpResponse() << LL_ENDL;
- //
- // if(mMediaImpl)
- // {
- // mMediaImpl->mMediaSourceFailed = true;
- // }
- // return;
- //}
-
- // 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;
-
- if(impl && !mInitialized && ! mime_type.empty())
- {
- if(impl->initializeMedia(mime_type))
- {
- mInitialized = true;
- impl->loadURI();
- disconnectOwner();
- }
- }
- }
-
-public:
- void cancelRequest()
- {
- disconnectOwner();
- }
-
-private:
- void disconnectOwner()
- {
- if(mMediaImpl)
- {
- if(mMediaImpl->mMimeTypeProbe != this)
- {
- LL_ERRS() << "internal error: mMediaImpl->mMimeTypeProbe != this" << LL_ENDL;
- }
-
- mMediaImpl->mMimeTypeProbe = NULL;
- }
- mMediaImpl = NULL;
- }
-
-
-public:
- LLViewerMediaImpl *mMediaImpl;
- bool mInitialized;
-};
-
-class LLViewerMediaOpenIDResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(LLViewerMediaOpenIDResponder);
-public:
- LLViewerMediaOpenIDResponder( )
- {
- }
-
- ~LLViewerMediaOpenIDResponder()
- {
- }
-
- /* virtual */ void completedRaw(
- const LLChannelDescriptors& channels,
- const LLIOPipe::buffer_ptr_t& buffer)
- {
- // We don't care about the content of the response, only the Set-Cookie header.
- LL_DEBUGS("MediaAuth") << dumpResponse()
- << " [headers:" << getResponseHeaders() << "]" << LL_ENDL;
- const std::string& cookie = getResponseHeader(HTTP_IN_HEADER_SET_COOKIE);
-
- // *TODO: What about bad status codes? Does this destroy previous cookies?
- LLViewerMedia::openIDCookieResponse(cookie);
- }
-
-};
-
-class LLViewerMediaWebProfileResponder : public LLHTTPClient::Responder
-{
-LOG_CLASS(LLViewerMediaWebProfileResponder);
-public:
- LLViewerMediaWebProfileResponder(std::string host)
- {
- mHost = host;
- }
-
- ~LLViewerMediaWebProfileResponder()
- {
- }
-
- void completedRaw(
- const LLChannelDescriptors& channels,
- const LLIOPipe::buffer_ptr_t& buffer)
- {
- // 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 = getResponseHeaders();
- // *TODO: Check that this works.
- stripped_content.erase(HTTP_IN_HEADER_SET_COOKIE);
- LL_WARNS("MediaAuth") << stripped_content << LL_ENDL;
-
- const std::string& cookie = getResponseHeader(HTTP_IN_HEADER_SET_COOKIE);
- 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.
- std::string auth_cookie = cookie.substr(0, cookie.find(";")); // strip path
- LLWebProfile::setAuthCookie(auth_cookie);
- }
-
- std::string mHost;
-};
-
-
LLPluginCookieStore *LLViewerMedia::sCookieStore = NULL;
LLURL LLViewerMedia::sOpenIDURL;
std::string LLViewerMedia::sOpenIDCookie;
@@ -1388,87 +1205,172 @@ LLSD LLViewerMedia::getHeaders()
return headers;
}
+LLCore::HttpHeaders::ptr_t LLViewerMedia::getHttpHeaders()
+{
+ LLCore::HttpHeaders::ptr_t headers(new LLCore::HttpHeaders);
+
+ headers->append(HTTP_OUT_HEADER_ACCEPT, "*/*");
+ headers->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_XML);
+ headers->append(HTTP_OUT_HEADER_COOKIE, sOpenIDCookie);
+ headers->append(HTTP_OUT_HEADER_USER_AGENT, getCurrentUserAgent());
+
+ return headers;
+}
+
/////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerMedia::setOpenIDCookie()
{
if(!sOpenIDCookie.empty())
{
- // The LLURL can give me the 'authority', which is of the form: [username[:password]@]hostname[:port]
- // We want just the hostname for the cookie code, but LLURL doesn't seem to have a way to extract that.
- // We therefore do it here.
- std::string authority = sOpenIDURL.mAuthority;
- std::string::size_type host_start = authority.find('@');
- if(host_start == std::string::npos)
- {
- // no username/password
- host_start = 0;
- }
- else
- {
- // Hostname starts after the @.
- // (If the hostname part is empty, this may put host_start at the end of the string. In that case, it will end up passing through an empty hostname, which is correct.)
- ++host_start;
- }
- std::string::size_type host_end = authority.rfind(':');
- if((host_end == std::string::npos) || (host_end < host_start))
- {
- // no port
- host_end = authority.size();
- }
-
- getCookieStore()->setCookiesFromHost(sOpenIDCookie, authority.substr(host_start, host_end - host_start));
+ std::string profileUrl = getProfileURL("");
+
+ LLCoros::instance().launch("LLViewerMedia::getOpenIDCookieCoro",
+ boost::bind(&LLViewerMedia::getOpenIDCookieCoro, profileUrl));
+ }
+}
+
+/*static*/
+void LLViewerMedia::getOpenIDCookieCoro(std::string url)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getOpenIDCookieCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
+
+ httpOpts->setFollowRedirects(true);
+ httpOpts->setWantHeaders(true);
+
+ LLURL hostUrl(url.c_str());
+ std::string hostAuth = hostUrl.getAuthority();
+
+ // *TODO: Expand LLURL to split and extract this information better.
+ // The structure of a URL is well defined and needing to retrieve parts of it are common.
+ // original comment:
+ // The LLURL can give me the 'authority', which is of the form: [username[:password]@]hostname[:port]
+ // We want just the hostname for the cookie code, but LLURL doesn't seem to have a way to extract that.
+ // We therefore do it here.
+ std::string authority = sOpenIDURL.mAuthority;
+ std::string::size_type hostStart = authority.find('@');
+ if (hostStart == std::string::npos)
+ { // no username/password
+ hostStart = 0;
+ }
+ else
+ { // Hostname starts after the @.
+ // (If the hostname part is empty, this may put host_start at the end of the string. In that case, it will end up passing through an empty hostname, which is correct.)
+ ++hostStart;
+ }
+ std::string::size_type hostEnd = authority.rfind(':');
+ if ((hostEnd == std::string::npos) || (hostEnd < hostStart))
+ { // no port
+ hostEnd = authority.size();
+ }
- // Do a web profile get so we can store the cookie
- LLSD headers = LLSD::emptyMap();
- headers[HTTP_OUT_HEADER_ACCEPT] = "*/*";
- headers[HTTP_OUT_HEADER_COOKIE] = sOpenIDCookie;
- headers[HTTP_OUT_HEADER_USER_AGENT] = getCurrentUserAgent();
+ getCookieStore()->setCookiesFromHost(sOpenIDCookie, authority.substr(hostStart, hostEnd - hostStart));
- std::string profile_url = getProfileURL("");
- LLURL raw_profile_url( profile_url.c_str() );
+ // Do a web profile get so we can store the cookie
+ httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, "*/*");
+ httpHeaders->append(HTTP_OUT_HEADER_COOKIE, sOpenIDCookie);
+ httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, getCurrentUserAgent());
+
+
+ LL_DEBUGS("MediaAuth") << "Requesting " << url << LL_ENDL;
+ LL_DEBUGS("MediaAuth") << "sOpenIDCookie = [" << sOpenIDCookie << "]" << LL_ENDL;
+
+ LLSD result = httpAdapter->getRawAndYield(httpRequest, url, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS("MediaAuth") << "Error getting web profile." << LL_ENDL;
+ return;
+ }
+
+ LLSD resultHeaders = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
+ if (!resultHeaders.has(HTTP_IN_HEADER_SET_COOKIE))
+ {
+ LL_WARNS("MediaAuth") << "No cookie in response." << LL_ENDL;
+ return;
+ }
+
+ const std::string& cookie = resultHeaders[HTTP_IN_HEADER_SET_COOKIE].asStringRef();
+ LL_DEBUGS("MediaAuth") << "cookie = " << cookie << LL_ENDL;
+
+ // *TODO: What about bad status codes? Does this destroy previous cookies?
+ LLViewerMedia::getCookieStore()->setCookiesFromHost(cookie, hostAuth);
+
+ // Set cookie for snapshot publishing.
+ std::string authCookie = cookie.substr(0, cookie.find(";")); // strip path
+ LLWebProfile::setAuthCookie(authCookie);
- LL_DEBUGS("MediaAuth") << "Requesting " << profile_url << LL_ENDL;
- LL_DEBUGS("MediaAuth") << "sOpenIDCookie = [" << sOpenIDCookie << "]" << LL_ENDL;
- LLHTTPClient::get(profile_url,
- new LLViewerMediaWebProfileResponder(raw_profile_url.getAuthority()),
- headers);
- }
}
/////////////////////////////////////////////////////////////////////////////////////////
// static
-void LLViewerMedia::openIDSetup(const std::string &openid_url, const std::string &openid_token)
+void LLViewerMedia::openIDSetup(const std::string &openidUrl, const std::string &openidToken)
{
- LL_DEBUGS("MediaAuth") << "url = \"" << openid_url << "\", token = \"" << openid_token << "\"" << LL_ENDL;
+ LL_DEBUGS("MediaAuth") << "url = \"" << openidUrl << "\", token = \"" << openidToken << "\"" << LL_ENDL;
- // post the token to the url
- // the responder will need to extract the cookie(s).
+ LLCoros::instance().launch("LLViewerMedia::openIDSetupCoro",
+ boost::bind(&LLViewerMedia::openIDSetupCoro, openidUrl, openidToken));
+}
- // Save the OpenID URL for later -- we may need the host when adding the cookie.
- sOpenIDURL.init(openid_url.c_str());
-
- // We shouldn't ever do this twice, but just in case this code gets repurposed later, clear existing cookies.
- sOpenIDCookie.clear();
+/*static*/
+void LLViewerMedia::openIDSetupCoro(std::string openidUrl, std::string openidToken)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("openIDSetupCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
- LLSD headers = LLSD::emptyMap();
- // Keep LLHTTPClient from adding an "Accept: application/llsd+xml" header
- headers[HTTP_OUT_HEADER_ACCEPT] = "*/*";
- // and use the expected content-type for a post, instead of the LLHTTPClient::postRaw() default of "application/octet-stream"
- headers[HTTP_OUT_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();
- U8 *data = new U8[size];
- memcpy(data, openid_token.data(), size);
-
- LLHTTPClient::postRaw(
- openid_url,
- data,
- size,
- new LLViewerMediaOpenIDResponder(),
- headers);
-
+ httpOpts->setWantHeaders(true);
+
+ // post the token to the url
+ // the responder will need to extract the cookie(s).
+ // Save the OpenID URL for later -- we may need the host when adding the cookie.
+ sOpenIDURL.init(openidUrl.c_str());
+ // We shouldn't ever do this twice, but just in case this code gets repurposed later, clear existing cookies.
+ sOpenIDCookie.clear();
+
+ httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, "*/*");
+ httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/x-www-form-urlencoded");
+
+ LLCore::BufferArray::ptr_t rawbody(new LLCore::BufferArray);
+ LLCore::BufferArrayStream bas(rawbody.get());
+
+ bas << std::noskipws << openidToken;
+
+ LLSD result = httpAdapter->postRawAndYield(httpRequest, openidUrl, rawbody, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS("MediaAuth") << "Error getting Open ID cookie" << LL_ENDL;
+ return;
+ }
+
+ LLSD resultHeaders = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
+ if (!resultHeaders.has(HTTP_IN_HEADER_SET_COOKIE))
+ {
+ LL_WARNS("MediaAuth") << "No cookie in response." << LL_ENDL;
+ return;
+ }
+
+ // We don't care about the content of the response, only the Set-Cookie header.
+ const std::string &cookie = resultHeaders[HTTP_IN_HEADER_SET_COOKIE];
+
+ // *TODO: What about bad status codes? Does this destroy previous cookies?
+ LLViewerMedia::openIDCookieResponse(cookie);
+ LL_DEBUGS("MediaAuth") << "OpenID cookie set." << LL_ENDL;
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -1661,7 +1563,6 @@ LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id,
mIsParcelMedia(false),
mProximity(-1),
mProximityDistance(0.0f),
- mMimeTypeProbe(NULL),
mMediaAutoPlay(false),
mInNearbyMediaList(false),
mClearCache(false),
@@ -1671,8 +1572,10 @@ LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id,
mIsUpdated(false),
mTrustedBrowser(false),
mZoomFactor(1.0),
- mCleanBrowser(false)
-{
+ mCleanBrowser(false),
+ mMimeProbe(),
+ mCanceling(false)
+{
// Set up the mute list observer if it hasn't been set up already.
if(!sViewerMediaMuteListObserverInitialized)
@@ -2610,7 +2513,8 @@ void LLViewerMediaImpl::navigateInternal()
return;
}
- if(mMimeTypeProbe != NULL)
+
+ if (!mMimeProbe.expired())
{
LL_WARNS() << "MIME type probe already in progress -- bailing out." << LL_ENDL;
return;
@@ -2648,14 +2552,8 @@ void LLViewerMediaImpl::navigateInternal()
if(scheme.empty() || "http" == scheme || "https" == scheme)
{
- // If we don't set an Accept header, LLHTTPClient will add one like this:
- // Accept: application/llsd+xml
- // which is really not what we want.
- LLSD headers = LLSD::emptyMap();
- headers[HTTP_OUT_HEADER_ACCEPT] = "*/*";
- // Allow cookies in the response, to prevent a redirect loop when accessing join.secondlife.com
- headers[HTTP_OUT_HEADER_COOKIE] = "";
- LLHTTPClient::getHeaderOnly( mMediaURL, new LLMimeDiscoveryResponder(this), headers, 10.0f);
+ LLCoros::instance().launch("LLViewerMediaImpl::mimeDiscoveryCoro",
+ boost::bind(&LLViewerMediaImpl::mimeDiscoveryCoro, this, mMediaURL));
}
else if("data" == scheme || "file" == scheme || "about" == scheme)
{
@@ -2685,6 +2583,66 @@ void LLViewerMediaImpl::navigateInternal()
}
}
+void LLViewerMediaImpl::mimeDiscoveryCoro(std::string url)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("mimeDiscoveryCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
+
+ mMimeProbe = httpAdapter;
+
+ httpOpts->setFollowRedirects(true);
+ httpOpts->setHeadersOnly(true);
+
+ httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, "*/*");
+ httpHeaders->append(HTTP_OUT_HEADER_COOKIE, "");
+
+ LLSD result = httpAdapter->getRawAndYield(httpRequest, url, httpOpts, httpHeaders);
+
+ mMimeProbe.reset();
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS() << "Error retrieving media headers." << LL_ENDL;
+ }
+
+ LLSD resultHeaders = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
+
+ const std::string& mediaType = resultHeaders[HTTP_IN_HEADER_CONTENT_TYPE].asStringRef();
+
+ std::string::size_type idx1 = mediaType.find_first_of(";");
+ std::string mimeType = mediaType.substr(0, idx1);
+
+ // We now no longer need to 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.
+ // The probe was successful.
+ if (mimeType.empty())
+ {
+ // Some sites don't return any content-type header at all.
+ // Treat an empty mime type as text/html.
+ mimeType = HTTP_CONTENT_TEXT_HTML;
+ }
+
+ LL_DEBUGS() << "Media type \"" << mediaType << "\", mime type is \"" << mimeType << "\"" << LL_ENDL;
+
+ // the call to initializeMedia may disconnect the responder, which will clear mMediaImpl.
+ // Make a local copy so we can call loadURI() afterwards.
+
+ if (!mimeType.empty())
+ {
+ if (initializeMedia(mimeType))
+ {
+ loadURI();
+ }
+ }
+}
+
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::navigateStop()
{
@@ -2783,7 +2741,7 @@ void LLViewerMediaImpl::update()
{
// Don't load new instances that are at PRIORITY_SLIDESHOW or below. They're just kept around to preserve state.
}
- else if(mMimeTypeProbe != NULL)
+ else if (!mMimeProbe.expired())
{
// this media source is doing a MIME type probe -- don't try loading it again.
}
@@ -3673,18 +3631,10 @@ void LLViewerMediaImpl::setNavigateSuspended(bool suspend)
void LLViewerMediaImpl::cancelMimeTypeProbe()
{
- if(mMimeTypeProbe != NULL)
- {
- // There doesn't seem to be a way to actually cancel an outstanding request.
- // Simulate it by telling the LLMimeDiscoveryResponder not to write back any results.
- mMimeTypeProbe->cancelRequest();
-
- // The above should already have set mMimeTypeProbe to NULL.
- if(mMimeTypeProbe != NULL)
- {
- LL_ERRS() << "internal error: mMimeTypeProbe is not NULL after cancelling request." << LL_ENDL;
- }
- }
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t probeAdapter = mMimeProbe.lock();
+
+ if (probeAdapter)
+ probeAdapter->cancelYieldingOperation();
}
void LLViewerMediaImpl::addObject(LLVOVolume* obj)
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index 6803adfaa2..92d644c900 100755
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -40,6 +40,9 @@
#include "llnotificationptr.h"
#include "llurl.h"
+#include "lleventcoro.h"
+#include "llcoros.h"
+#include "llcorehttputil.h"
class LLViewerMediaImpl;
class LLUUID;
@@ -161,11 +164,15 @@ public:
static void setOnlyAudibleMediaTextureID(const LLUUID& texture_id);
static LLSD getHeaders();
+ static LLCore::HttpHeaders::ptr_t getHttpHeaders();
private:
static void setOpenIDCookie();
static void onTeleportFinished();
-
+
+ static void openIDSetupCoro(std::string openidUrl, std::string openidToken);
+ static void getOpenIDCookieCoro(std::string url);
+
static LLPluginCookieStore *sCookieStore;
static LLURL sOpenIDURL;
static std::string sOpenIDCookie;
@@ -180,7 +187,6 @@ class LLViewerMediaImpl
public:
friend class LLViewerMedia;
- friend class LLMimeDiscoveryResponder;
LLViewerMediaImpl(
const LLUUID& texture_id,
@@ -453,7 +459,6 @@ private:
S32 mProximity;
F64 mProximityDistance;
F64 mProximityCamera;
- LLMimeDiscoveryResponder *mMimeTypeProbe;
bool mMediaAutoPlay;
std::string mMediaEntryURL;
bool mInNearbyMediaList; // used by LLPanelNearbyMedia::refreshList() for performance reasons
@@ -470,6 +475,10 @@ private:
BOOL mIsUpdated ;
std::list< LLVOVolume* > mObjectList ;
+ void mimeDiscoveryCoro(std::string url);
+ LLCoreHttpUtil::HttpCoroutineAdapter::wptr_t mMimeProbe;
+ bool mCanceling;
+
private:
LLViewerMediaTexture *updatePlaceholderImage();
};
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index f8e50ba463..163ae4f4ec 100755
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -62,6 +62,7 @@
#include "lluploaddialog.h"
#include "lltrans.h"
#include "llfloaterbuycurrency.h"
+#include "llviewerassetupload.h"
// linden libraries
#include "llassetuploadresponders.h"
@@ -83,8 +84,9 @@ class LLFileEnableUpload : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- bool new_value = gStatusBar && LLGlobalEconomy::Singleton::getInstance() && (gStatusBar->getBalance() >= LLGlobalEconomy::Singleton::getInstance()->getPriceUpload());
- return new_value;
+ return true;
+// bool new_value = gStatusBar && LLGlobalEconomy::Singleton::getInstance() && (gStatusBar->getBalance() >= LLGlobalEconomy::Singleton::getInstance()->getPriceUpload());
+// return new_value;
}
};
@@ -410,7 +412,6 @@ class LLFileUploadBulk : public view_listener_t
}
// TODO:
- // Iterate over all files
// Check extensions for uploadability, cost
// Check user balance for entire cost
// Charge user entire cost
@@ -422,37 +423,33 @@ class LLFileUploadBulk : public view_listener_t
LLFilePicker& picker = LLFilePicker::instance();
if (picker.getMultipleOpenFiles())
{
- const std::string& filename = picker.getFirstFile();
- std::string name = gDirUtilp->getBaseFileName(filename, true);
-
- std::string asset_name = name;
- LLStringUtil::replaceNonstandardASCII( asset_name, '?' );
- LLStringUtil::replaceChar(asset_name, '|', '?');
- LLStringUtil::stripNonprintable(asset_name);
- LLStringUtil::trim(asset_name);
-
- std::string display_name = LLStringUtil::null;
- LLAssetStorage::LLStoreAssetCallback callback = NULL;
- S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
- void *userdata = NULL;
-
- upload_new_resource(
- filename,
- asset_name,
- asset_name,
- 0,
- LLFolderType::FT_NONE,
- LLInventoryType::IT_NONE,
- LLFloaterPerms::getNextOwnerPerms("Uploads"),
- LLFloaterPerms::getGroupPerms("Uploads"),
- LLFloaterPerms::getEveryonePerms("Uploads"),
- display_name,
- callback,
- expected_upload_cost,
- userdata);
-
- // *NOTE: Ew, we don't iterate over the file list here,
- // we handle the next files in upload_done_callback()
+ std::string filename = picker.getFirstFile();
+ S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
+
+ while (!filename.empty())
+ {
+ std::string name = gDirUtilp->getBaseFileName(filename, true);
+
+ std::string asset_name = name;
+ LLStringUtil::replaceNonstandardASCII( asset_name, '?' );
+ LLStringUtil::replaceChar(asset_name, '|', '?');
+ LLStringUtil::stripNonprintable(asset_name);
+ LLStringUtil::trim(asset_name);
+
+ LLResourceUploadInfo::ptr_t uploadInfo(new NewFileResourceUploadInfo(
+ filename,
+ asset_name,
+ asset_name, 0,
+ LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
+ LLFloaterPerms::getNextOwnerPerms("Uploads"),
+ LLFloaterPerms::getGroupPerms("Uploads"),
+ LLFloaterPerms::getEveryonePerms("Uploads"),
+ expected_upload_cost));
+
+ upload_new_resource(uploadInfo, NULL, NULL);
+
+ filename = picker.getNextFile();
+ }
}
else
{
@@ -621,6 +618,7 @@ void handle_compress_image(void*)
}
}
+
LLUUID upload_new_resource(
const std::string& src_filename,
std::string name,
@@ -636,276 +634,16 @@ LLUUID upload_new_resource(
S32 expected_upload_cost,
void *userdata)
{
- // Generate the temporary UUID.
- std::string filename = gDirUtilp->getTempFilename();
- LLTransactionID tid;
- LLAssetID uuid;
-
- LLSD args;
-
- std::string exten = gDirUtilp->getExtension(src_filename);
- U32 codec = LLImageBase::getCodecFromExtension(exten);
- LLAssetType::EType asset_type = LLAssetType::AT_NONE;
- std::string error_message;
-
- BOOL error = FALSE;
-
- if (exten.empty())
- {
- std::string short_name = gDirUtilp->getBaseFileName(filename);
-
- // No extension
- error_message = llformat(
- "No file extension for the file: '%s'\nPlease make sure the file has a correct file extension",
- short_name.c_str());
- args["FILE"] = short_name;
- upload_error(error_message, "NoFileExtension", filename, args);
- return LLUUID();
- }
- else if (codec != IMG_CODEC_INVALID)
- {
- // It's an image file, the upload procedure is the same for all
- asset_type = LLAssetType::AT_TEXTURE;
- if (!LLViewerTextureList::createUploadFile(src_filename, filename, codec ))
- {
- error_message = llformat( "Problem with file %s:\n\n%s\n",
- src_filename.c_str(), LLImage::getLastError().c_str());
- args["FILE"] = src_filename;
- args["ERROR"] = LLImage::getLastError();
- upload_error(error_message, "ProblemWithFile", filename, args);
- return LLUUID();
- }
- }
- else if(exten == "wav")
- {
- asset_type = LLAssetType::AT_SOUND; // tag it as audio
- S32 encode_result = 0;
-
- LL_INFOS() << "Attempting to encode wav as an ogg file" << LL_ENDL;
-
- encode_result = encode_vorbis_file(src_filename, filename);
-
- if (LLVORBISENC_NOERR != encode_result)
- {
- switch(encode_result)
- {
- case LLVORBISENC_DEST_OPEN_ERR:
- error_message = llformat( "Couldn't open temporary compressed sound file for writing: %s\n", filename.c_str());
- args["FILE"] = filename;
- upload_error(error_message, "CannotOpenTemporarySoundFile", filename, args);
- break;
-
- default:
- error_message = llformat("Unknown vorbis encode failure on: %s\n", src_filename.c_str());
- args["FILE"] = src_filename;
- upload_error(error_message, "UnknownVorbisEncodeFailure", filename, args);
- break;
- }
- return LLUUID();
- }
- }
- else if(exten == "tmp")
- {
- // This is a generic .lin resource file
- asset_type = LLAssetType::AT_OBJECT;
- LLFILE* in = LLFile::fopen(src_filename, "rb"); /* Flawfinder: ignore */
- if (in)
- {
- // read in the file header
- char buf[16384]; /* Flawfinder: ignore */
- size_t readbytes;
- S32 version;
- if (fscanf(in, "LindenResource\nversion %d\n", &version))
- {
- if (2 == version)
- {
- // *NOTE: This buffer size is hard coded into scanf() below.
- char label[MAX_STRING]; /* Flawfinder: ignore */
- char value[MAX_STRING]; /* Flawfinder: ignore */
- S32 tokens_read;
- while (fgets(buf, 1024, in))
- {
- label[0] = '\0';
- value[0] = '\0';
- tokens_read = sscanf( /* Flawfinder: ignore */
- buf,
- "%254s %254s\n",
- label, value);
-
- LL_INFOS() << "got: " << label << " = " << value
- << LL_ENDL;
-
- if (EOF == tokens_read)
- {
- fclose(in);
- error_message = llformat("corrupt resource file: %s", src_filename.c_str());
- args["FILE"] = src_filename;
- upload_error(error_message, "CorruptResourceFile", filename, args);
- return LLUUID();
- }
-
- if (2 == tokens_read)
- {
- if (! strcmp("type", label))
- {
- asset_type = (LLAssetType::EType)(atoi(value));
- }
- }
- else
- {
- if (! strcmp("_DATA_", label))
- {
- // below is the data section
- break;
- }
- }
- // other values are currently discarded
- }
-
- }
- else
- {
- fclose(in);
- error_message = llformat("unknown linden resource file version in file: %s", src_filename.c_str());
- args["FILE"] = src_filename;
- upload_error(error_message, "UnknownResourceFileVersion", filename, args);
- return LLUUID();
- }
- }
- else
- {
- // this is an original binary formatted .lin file
- // start over at the beginning of the file
- fseek(in, 0, SEEK_SET);
-
- const S32 MAX_ASSET_DESCRIPTION_LENGTH = 256;
- const S32 MAX_ASSET_NAME_LENGTH = 64;
- S32 header_size = 34 + MAX_ASSET_DESCRIPTION_LENGTH + MAX_ASSET_NAME_LENGTH;
- S16 type_num;
-
- // read in and throw out most of the header except for the type
- if (fread(buf, header_size, 1, in) != 1)
- {
- LL_WARNS() << "Short read" << LL_ENDL;
- }
- memcpy(&type_num, buf + 16, sizeof(S16)); /* Flawfinder: ignore */
- asset_type = (LLAssetType::EType)type_num;
- }
-
- // copy the file's data segment into another file for uploading
- LLFILE* out = LLFile::fopen(filename, "wb"); /* Flawfinder: ignore */
- if (out)
- {
- while((readbytes = fread(buf, 1, 16384, in))) /* Flawfinder: ignore */
- {
- if (fwrite(buf, 1, readbytes, out) != readbytes)
- {
- LL_WARNS() << "Short write" << LL_ENDL;
- }
- }
- fclose(out);
- }
- else
- {
- fclose(in);
- error_message = llformat( "Unable to create output file: %s", filename.c_str());
- args["FILE"] = filename;
- upload_error(error_message, "UnableToCreateOutputFile", filename, args);
- return LLUUID();
- }
-
- fclose(in);
- }
- else
- {
- LL_INFOS() << "Couldn't open .lin file " << src_filename << LL_ENDL;
- }
- }
- else if (exten == "bvh")
- {
- error_message = llformat("We do not currently support bulk upload of animation files\n");
- upload_error(error_message, "DoNotSupportBulkAnimationUpload", filename, args);
- return LLUUID();
- }
- else if (exten == "anim")
- {
- asset_type = LLAssetType::AT_ANIMATION;
- filename = src_filename;
- }
- else
- {
- // Unknown extension
- error_message = llformat(LLTrans::getString("UnknownFileExtension").c_str(), exten.c_str());
- error = TRUE;;
- }
-
- // gen a new transaction ID for this asset
- tid.generate();
- if (!error)
- {
- uuid = tid.makeAssetID(gAgent.getSecureSessionID());
- // copy this file into the vfs for upload
- S32 file_size;
- LLAPRFile infile ;
- infile.open(filename, LL_APR_RB, NULL, &file_size);
- if (infile.getFileHandle())
- {
- LLVFile file(gVFS, uuid, asset_type, LLVFile::WRITE);
-
- file.setMaxSize(file_size);
-
- const S32 buf_size = 65536;
- U8 copy_buf[buf_size];
- while ((file_size = infile.read(copy_buf, buf_size)))
- {
- file.write(copy_buf, file_size);
- }
- }
- else
- {
- error_message = llformat( "Unable to access output file: %s", filename.c_str());
- error = TRUE;
- }
- }
-
- if (!error)
- {
- std::string t_disp_name = display_name;
- if (t_disp_name.empty())
- {
- t_disp_name = src_filename;
- }
- upload_new_resource(
- tid,
- asset_type,
- name,
- desc,
- compression_info, // tid
- destination_folder_type,
- inv_type,
- next_owner_perms,
- group_perms,
- everyone_perms,
- display_name,
- callback,
- expected_upload_cost,
- userdata);
- }
- else
- {
- LL_WARNS() << error_message << LL_ENDL;
- LLSD args;
- args["ERROR_MESSAGE"] = error_message;
- LLNotificationsUtil::add("ErrorMessage", args);
- if(LLFile::remove(filename) == -1)
- {
- LL_DEBUGS() << "unable to remove temp file" << LL_ENDL;
- }
- LLFilePicker::instance().reset();
- }
+ LLResourceUploadInfo::ptr_t uploadInfo(new NewFileResourceUploadInfo(
+ src_filename,
+ name, desc, compression_info,
+ destination_folder_type, inv_type,
+ next_owner_perms, group_perms, everyone_perms,
+ expected_upload_cost));
+ upload_new_resource(uploadInfo, callback, userdata);
- return uuid;
+ return LLUUID::null;
}
void upload_done_callback(
@@ -1035,189 +773,62 @@ void upload_done_callback(
}
}
-static LLAssetID upload_new_resource_prep(
- const LLTransactionID& tid,
- LLAssetType::EType asset_type,
- LLInventoryType::EType& inventory_type,
- std::string& name,
- const std::string& display_name,
- std::string& description)
-{
- LLAssetID uuid = generate_asset_id_for_new_upload(tid);
-
- increase_new_upload_stats(asset_type);
-
- assign_defaults_and_show_upload_message(
- asset_type,
- inventory_type,
- name,
- display_name,
- description);
-
- return uuid;
-}
-
-LLSD generate_new_resource_upload_capability_body(
- LLAssetType::EType asset_type,
- const std::string& name,
- const std::string& desc,
- LLFolderType::EType destination_folder_type,
- LLInventoryType::EType inv_type,
- U32 next_owner_perms,
- U32 group_perms,
- U32 everyone_perms)
-{
- LLSD body;
-
- body["folder_id"] = gInventory.findCategoryUUIDForType(
- (destination_folder_type == LLFolderType::FT_NONE) ?
- (LLFolderType::EType) asset_type :
- destination_folder_type);
-
- body["asset_type"] = LLAssetType::lookup(asset_type);
- body["inventory_type"] = LLInventoryType::lookup(inv_type);
- body["name"] = name;
- body["description"] = desc;
- body["next_owner_mask"] = LLSD::Integer(next_owner_perms);
- body["group_mask"] = LLSD::Integer(group_perms);
- body["everyone_mask"] = LLSD::Integer(everyone_perms);
-
- return body;
-}
-
void upload_new_resource(
- const LLTransactionID &tid,
- LLAssetType::EType asset_type,
- std::string name,
- std::string desc,
- S32 compression_info,
- LLFolderType::EType destination_folder_type,
- LLInventoryType::EType inv_type,
- U32 next_owner_perms,
- U32 group_perms,
- U32 everyone_perms,
- const std::string& display_name,
- LLAssetStorage::LLStoreAssetCallback callback,
- S32 expected_upload_cost,
- void *userdata)
+ LLResourceUploadInfo::ptr_t &uploadInfo,
+ LLAssetStorage::LLStoreAssetCallback callback,
+ void *userdata)
{
if(gDisconnected)
{
return ;
}
-
- LLAssetID uuid =
- upload_new_resource_prep(
- tid,
- asset_type,
- inv_type,
- name,
- display_name,
- desc);
-
- if( LLAssetType::AT_SOUND == asset_type )
- {
- add(LLStatViewer::UPLOAD_SOUND, 1);
- }
- else
- if( LLAssetType::AT_TEXTURE == asset_type )
- {
- add(LLStatViewer::UPLOAD_TEXTURE, 1);
- }
- else
- if( LLAssetType::AT_ANIMATION == asset_type)
- {
- add(LLStatViewer::ANIMATION_UPLOADS, 1);
- }
- if(LLInventoryType::IT_NONE == inv_type)
- {
- inv_type = LLInventoryType::defaultForAssetType(asset_type);
- }
- LLStringUtil::stripNonprintable(name);
- LLStringUtil::stripNonprintable(desc);
- if(name.empty())
- {
- name = "(No Name)";
- }
- if(desc.empty())
- {
- desc = "(No Description)";
- }
-
- // At this point, we're ready for the upload.
- std::string upload_message = "Uploading...\n\n";
- upload_message.append(display_name);
- LLUploadDialog::modalUploadDialog(upload_message);
-
- LL_INFOS() << "*** Uploading: " << LL_ENDL;
- LL_INFOS() << "Type: " << LLAssetType::lookup(asset_type) << LL_ENDL;
- LL_INFOS() << "UUID: " << uuid << LL_ENDL;
- LL_INFOS() << "Name: " << name << LL_ENDL;
- LL_INFOS() << "Desc: " << desc << LL_ENDL;
- LL_INFOS() << "Expected Upload Cost: " << expected_upload_cost << LL_ENDL;
- LL_DEBUGS() << "Folder: " << gInventory.findCategoryUUIDForType((destination_folder_type == LLFolderType::FT_NONE) ? LLFolderType::assetTypeToFolderType(asset_type) : destination_folder_type) << LL_ENDL;
- LL_DEBUGS() << "Asset Type: " << LLAssetType::lookup(asset_type) << LL_ENDL;
-
- std::string url = gAgent.getRegion()->getCapability(
- "NewFileAgentInventory");
+// uploadInfo->setAssetType(assetType);
+// uploadInfo->setTransactionId(tid);
+
+
+ std::string url = gAgent.getRegion()->getCapability("NewFileAgentInventory");
if ( !url.empty() )
{
- LL_INFOS() << "New Agent Inventory via capability" << LL_ENDL;
-
- LLSD body;
- body = generate_new_resource_upload_capability_body(
- asset_type,
- name,
- desc,
- destination_folder_type,
- inv_type,
- next_owner_perms,
- group_perms,
- everyone_perms);
-
- LLHTTPClient::post(
- url,
- body,
- new LLNewAgentInventoryResponder(
- body,
- uuid,
- asset_type));
+ LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo);
}
else
{
+ uploadInfo->prepareUpload();
+ uploadInfo->logPreparedUpload();
+
LL_INFOS() << "NewAgentInventory capability not found, new agent inventory via asset system." << LL_ENDL;
// check for adequate funds
// TODO: do this check on the sim
- if (LLAssetType::AT_SOUND == asset_type ||
- LLAssetType::AT_TEXTURE == asset_type ||
- LLAssetType::AT_ANIMATION == asset_type)
+ if (LLAssetType::AT_SOUND == uploadInfo->getAssetType() ||
+ LLAssetType::AT_TEXTURE == uploadInfo->getAssetType() ||
+ LLAssetType::AT_ANIMATION == uploadInfo->getAssetType())
{
S32 balance = gStatusBar->getBalance();
- if (balance < expected_upload_cost)
+ if (balance < uploadInfo->getExpectedUploadCost())
{
// insufficient funds, bail on this upload
LLStringUtil::format_map_t args;
- args["NAME"] = name;
- args["AMOUNT"] = llformat("%d", expected_upload_cost);
- LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("UploadingCosts", args), expected_upload_cost );
+ args["NAME"] = uploadInfo->getName();
+ args["AMOUNT"] = llformat("%d", uploadInfo->getExpectedUploadCost());
+ LLBuyCurrencyHTML::openCurrencyFloater(LLTrans::getString("UploadingCosts", args), uploadInfo->getExpectedUploadCost());
return;
}
}
LLResourceData* data = new LLResourceData;
- data->mAssetInfo.mTransactionID = tid;
- data->mAssetInfo.mUuid = uuid;
- data->mAssetInfo.mType = asset_type;
+ data->mAssetInfo.mTransactionID = uploadInfo->getTransactionId();
+ data->mAssetInfo.mUuid = uploadInfo->getAssetId();
+ data->mAssetInfo.mType = uploadInfo->getAssetType();
data->mAssetInfo.mCreatorID = gAgentID;
- data->mInventoryType = inv_type;
- data->mNextOwnerPerm = next_owner_perms;
- data->mExpectedUploadCost = expected_upload_cost;
+ data->mInventoryType = uploadInfo->getInventoryType();
+ data->mNextOwnerPerm = uploadInfo->getNextOwnerPerms();
+ data->mExpectedUploadCost = uploadInfo->getExpectedUploadCost();
data->mUserData = userdata;
- data->mAssetInfo.setName(name);
- data->mAssetInfo.setDescription(desc);
- data->mPreferredLocation = destination_folder_type;
+ data->mAssetInfo.setName(uploadInfo->getName());
+ data->mAssetInfo.setDescription(uploadInfo->getDescription());
+ data->mPreferredLocation = uploadInfo->getDestinationFolderType();
LLAssetStorage::LLStoreAssetCallback asset_callback = &upload_done_callback;
if (callback)
@@ -1233,66 +844,6 @@ void upload_new_resource(
}
}
-LLAssetID generate_asset_id_for_new_upload(const LLTransactionID& tid)
-{
- if ( gDisconnected )
- {
- LLAssetID rv;
-
- rv.setNull();
- return rv;
- }
-
- LLAssetID uuid = tid.makeAssetID(gAgent.getSecureSessionID());
-
- return uuid;
-}
-
-void increase_new_upload_stats(LLAssetType::EType asset_type)
-{
- if ( LLAssetType::AT_SOUND == asset_type )
- {
- add(LLStatViewer::UPLOAD_SOUND, 1);
- }
- else if ( LLAssetType::AT_TEXTURE == asset_type )
- {
- add(LLStatViewer::UPLOAD_TEXTURE, 1);
- }
- else if ( LLAssetType::AT_ANIMATION == asset_type )
- {
- add(LLStatViewer::ANIMATION_UPLOADS, 1);
- }
-}
-
-void assign_defaults_and_show_upload_message(
- LLAssetType::EType asset_type,
- LLInventoryType::EType& inventory_type,
- std::string& name,
- const std::string& display_name,
- std::string& description)
-{
- if ( LLInventoryType::IT_NONE == inventory_type )
- {
- inventory_type = LLInventoryType::defaultForAssetType(asset_type);
- }
- LLStringUtil::stripNonprintable(name);
- LLStringUtil::stripNonprintable(description);
-
- if ( name.empty() )
- {
- name = "(No Name)";
- }
- if ( description.empty() )
- {
- description = "(No Description)";
- }
-
- // At this point, we're ready for the upload.
- std::string upload_message = "Uploading...\n\n";
- upload_message.append(display_name);
- LLUploadDialog::modalUploadDialog(upload_message);
-}
-
void init_menu_file()
{
diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h
index 3034d00b22..0f8fa56b52 100755
--- a/indra/newview/llviewermenufile.h
+++ b/indra/newview/llviewermenufile.h
@@ -34,45 +34,35 @@
#include "llthread.h"
#include <queue>
+#include "llviewerassetupload.h"
+
class LLTransactionID;
void init_menu_file();
+
LLUUID upload_new_resource(
- const std::string& src_filename,
- std::string name,
- std::string desc,
- S32 compression_info,
- LLFolderType::EType destination_folder_type,
- LLInventoryType::EType inv_type,
- U32 next_owner_perms,
- U32 group_perms,
- U32 everyone_perms,
- const std::string& display_name,
- LLAssetStorage::LLStoreAssetCallback callback,
- S32 expected_upload_cost,
- void *userdata);
+ const std::string& src_filename,
+ std::string name,
+ std::string desc,
+ S32 compression_info,
+ LLFolderType::EType destination_folder_type,
+ LLInventoryType::EType inv_type,
+ U32 next_owner_perms,
+ U32 group_perms,
+ U32 everyone_perms,
+ const std::string& display_name,
+ LLAssetStorage::LLStoreAssetCallback callback,
+ S32 expected_upload_cost,
+ void *userdata);
void upload_new_resource(
- const LLTransactionID &tid,
- LLAssetType::EType type,
- std::string name,
- std::string desc,
- S32 compression_info,
- LLFolderType::EType destination_folder_type,
- LLInventoryType::EType inv_type,
- U32 next_owner_perms,
- U32 group_perms,
- U32 everyone_perms,
- const std::string& display_name,
- LLAssetStorage::LLStoreAssetCallback callback,
- S32 expected_upload_cost,
- void *userdata);
+ LLResourceUploadInfo::ptr_t &uploadInfo,
+ LLAssetStorage::LLStoreAssetCallback callback = NULL,
+ void *userdata = NULL);
-LLAssetID generate_asset_id_for_new_upload(const LLTransactionID& tid);
-void increase_new_upload_stats(LLAssetType::EType asset_type);
void assign_defaults_and_show_upload_message(
LLAssetType::EType asset_type,
LLInventoryType::EType& inventory_type,
@@ -80,16 +70,6 @@ void assign_defaults_and_show_upload_message(
const std::string& display_name,
std::string& description);
-LLSD generate_new_resource_upload_capability_body(
- LLAssetType::EType asset_type,
- const std::string& name,
- const std::string& desc,
- LLFolderType::EType destination_folder_type,
- LLInventoryType::EType inv_type,
- U32 next_owner_perms,
- U32 group_perms,
- U32 everyone_perms);
-
void on_new_single_inventory_upload_complete(
LLAssetType::EType asset_type,
LLInventoryType::EType inventory_type,
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 75732a1e19..9b0035d547 100755
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -78,6 +78,7 @@
#include "llappviewer.h"
#include "llfloaterperms.h"
#include "llvocache.h"
+#include "llcorehttputil.h"
extern F32 gMinObjectDistance;
extern BOOL gAnimateTextures;
@@ -795,190 +796,6 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent)
LLVOAvatar::cullAvatarsByPixelArea();
}
-class LLObjectCostResponder : public LLCurl::Responder
-{
- LOG_CLASS(LLObjectCostResponder);
-public:
- LLObjectCostResponder(const LLSD& object_ids)
- : mObjectIDs(object_ids)
- {
- }
-
- // Clear's the global object list's pending
- // request list for all objects requested
- void clear_object_list_pending_requests()
- {
- // TODO*: No more hard coding
- for (
- LLSD::array_iterator iter = mObjectIDs.beginArray();
- iter != mObjectIDs.endArray();
- ++iter)
- {
- gObjectList.onObjectCostFetchFailure(iter->asUUID());
- }
- }
-
-private:
- /* virtual */ void httpFailure()
- {
- LL_WARNS() << dumpResponse() << LL_ENDL;
-
- // TODO*: Error message to user
- // For now just clear the request from the pending list
- clear_object_list_pending_requests();
- }
-
- /* virtual */ void httpSuccess()
- {
- const LLSD& content = getContent();
- if ( !content.isMap() || content.has("error") )
- {
- // Improper response or the request had an error,
- // show an error to the user?
- LL_WARNS()
- << "Application level error when fetching object "
- << "cost. Message: " << content["error"]["message"].asString()
- << ", identifier: " << content["error"]["identifier"].asString()
- << LL_ENDL;
-
- // TODO*: Adaptively adjust request size if the
- // service says we've requested too many and retry
-
- // TODO*: Error message if not retrying
- clear_object_list_pending_requests();
- return;
- }
-
- // Success, grab the resource cost and linked set costs
- // for an object if one was returned
- for (
- LLSD::array_iterator iter = mObjectIDs.beginArray();
- iter != mObjectIDs.endArray();
- ++iter)
- {
- LLUUID object_id = iter->asUUID();
-
- // Check to see if the request contains data for the object
- if ( content.has(iter->asString()) )
- {
- F32 link_cost =
- content[iter->asString()]["linked_set_resource_cost"].asReal();
- F32 object_cost =
- content[iter->asString()]["resource_cost"].asReal();
-
- F32 physics_cost = content[iter->asString()]["physics_cost"].asReal();
- F32 link_physics_cost = content[iter->asString()]["linked_set_physics_cost"].asReal();
-
- gObjectList.updateObjectCost(object_id, object_cost, link_cost, physics_cost, link_physics_cost);
- }
- else
- {
- // TODO*: Give user feedback about the missing data?
- gObjectList.onObjectCostFetchFailure(object_id);
- }
- }
- }
-
-private:
- LLSD mObjectIDs;
-};
-
-
-class LLPhysicsFlagsResponder : public LLCurl::Responder
-{
- LOG_CLASS(LLPhysicsFlagsResponder);
-public:
- LLPhysicsFlagsResponder(const LLSD& object_ids)
- : mObjectIDs(object_ids)
- {
- }
-
- // Clear's the global object list's pending
- // request list for all objects requested
- void clear_object_list_pending_requests()
- {
- // TODO*: No more hard coding
- for (
- LLSD::array_iterator iter = mObjectIDs.beginArray();
- iter != mObjectIDs.endArray();
- ++iter)
- {
- gObjectList.onPhysicsFlagsFetchFailure(iter->asUUID());
- }
- }
-
-private:
- /* virtual */ void httpFailure()
- {
- LL_WARNS() << dumpResponse() << LL_ENDL;
-
- // TODO*: Error message to user
- // For now just clear the request from the pending list
- clear_object_list_pending_requests();
- }
-
- /* virtual void */ void httpSuccess()
- {
- const LLSD& content = getContent();
- if ( !content.isMap() || content.has("error") )
- {
- // Improper response or the request had an error,
- // show an error to the user?
- LL_WARNS()
- << "Application level error when fetching object "
- << "physics flags. Message: " << content["error"]["message"].asString()
- << ", identifier: " << content["error"]["identifier"].asString()
- << LL_ENDL;
-
- // TODO*: Adaptively adjust request size if the
- // service says we've requested too many and retry
-
- // TODO*: Error message if not retrying
- clear_object_list_pending_requests();
- return;
- }
-
- // Success, grab the resource cost and linked set costs
- // for an object if one was returned
- for (
- LLSD::array_iterator iter = mObjectIDs.beginArray();
- iter != mObjectIDs.endArray();
- ++iter)
- {
- LLUUID object_id = iter->asUUID();
-
- // Check to see if the request contains data for the object
- if ( content.has(iter->asString()) )
- {
- const LLSD& data = content[iter->asString()];
-
- S32 shape_type = data["PhysicsShapeType"].asInteger();
-
- gObjectList.updatePhysicsShapeType(object_id, shape_type);
-
- if (data.has("Density"))
- {
- F32 density = data["Density"].asReal();
- F32 friction = data["Friction"].asReal();
- F32 restitution = data["Restitution"].asReal();
- F32 gravity_multiplier = data["GravityMultiplier"].asReal();
-
- gObjectList.updatePhysicsProperties(object_id,
- density, friction, restitution, gravity_multiplier);
- }
- }
- else
- {
- // TODO*: Give user feedback about the missing data?
- gObjectList.onPhysicsFlagsFetchFailure(object_id);
- }
- }
- }
-
-private:
- LLSD mObjectIDs;
-};
-
static LLTrace::BlockTimerStatHandle FTM_IDLE_COPY("Idle Copy");
void LLViewerObjectList::update(LLAgent &agent)
@@ -1174,41 +991,8 @@ void LLViewerObjectList::fetchObjectCosts()
if (!url.empty())
{
- LLSD id_list;
- U32 object_index = 0;
-
- for (
- std::set<LLUUID>::iterator iter = mStaleObjectCost.begin();
- iter != mStaleObjectCost.end();
- )
- {
- // Check to see if a request for this object
- // has already been made.
- if ( mPendingObjectCost.find(*iter) ==
- mPendingObjectCost.end() )
- {
- mPendingObjectCost.insert(*iter);
- id_list[object_index++] = *iter;
- }
-
- mStaleObjectCost.erase(iter++);
-
- if (object_index >= MAX_CONCURRENT_PHYSICS_REQUESTS)
- {
- break;
- }
- }
-
- if ( id_list.size() > 0 )
- {
- LLSD post_data = LLSD::emptyMap();
-
- post_data["object_ids"] = id_list;
- LLHTTPClient::post(
- url,
- post_data,
- new LLObjectCostResponder(id_list));
- }
+ LLCoros::instance().launch("LLViewerObjectList::fetchObjectCostsCoro",
+ boost::bind(&LLViewerObjectList::fetchObjectCostsCoro, this, url));
}
else
{
@@ -1219,6 +1003,111 @@ void LLViewerObjectList::fetchObjectCosts()
}
}
+/*static*/
+void LLViewerObjectList::reportObjectCostFailure(LLSD &objectList)
+{
+ // TODO*: No more hard coding
+ for (LLSD::array_iterator it = objectList.beginArray(); it != objectList.endArray(); ++it)
+ {
+ gObjectList.onObjectCostFetchFailure(it->asUUID());
+ }
+}
+
+
+void LLViewerObjectList::fetchObjectCostsCoro(std::string url)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("genericPostCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLSD idList;
+ U32 objectIndex = 0;
+
+ for (std::set<LLUUID>::iterator it = mStaleObjectCost.begin(); it != mStaleObjectCost.end(); )
+ {
+ // Check to see if a request for this object
+ // has already been made.
+ if (mPendingObjectCost.find(*it) == mPendingObjectCost.end())
+ {
+ mPendingObjectCost.insert(*it);
+ idList[objectIndex++] = *it;
+ }
+
+ mStaleObjectCost.erase(it++);
+
+ if (objectIndex >= MAX_CONCURRENT_PHYSICS_REQUESTS)
+ {
+ break;
+ }
+ }
+
+ if (idList.size() < 1)
+ {
+ LL_INFOS() << "No outstanding object IDs to request." << LL_ENDL;
+ return;
+ }
+
+ LLSD postData = LLSD::emptyMap();
+
+ postData["object_ids"] = idList;
+
+ LLSD result = httpAdapter->postAndYield(httpRequest, url, postData);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status || result.has("error"))
+ {
+ if (result.has("error"))
+ {
+ LL_WARNS() << "Application level error when fetching object "
+ << "cost. Message: " << result["error"]["message"].asString()
+ << ", identifier: " << result["error"]["identifier"].asString()
+ << LL_ENDL;
+
+ // TODO*: Adaptively adjust request size if the
+ // service says we've requested too many and retry
+ }
+ reportObjectCostFailure(idList);
+
+ return;
+ }
+
+ // Success, grab the resource cost and linked set costs
+ // for an object if one was returned
+ for (LLSD::array_iterator it = idList.beginArray(); it != idList.endArray(); ++it)
+ {
+ LLUUID objectId = it->asUUID();
+
+ // Check to see if the request contains data for the object
+ if (result.has(it->asString()))
+ {
+ const LLSD& data = result[it->asString()];
+
+ S32 shapeType = data["PhysicsShapeType"].asInteger();
+
+ gObjectList.updatePhysicsShapeType(objectId, shapeType);
+
+ if (data.has("Density"))
+ {
+ F32 density = data["Density"].asReal();
+ F32 friction = data["Friction"].asReal();
+ F32 restitution = data["Restitution"].asReal();
+ F32 gravityMult = data["GravityMultiplier"].asReal();
+
+ gObjectList.updatePhysicsProperties(objectId, density, friction, restitution, gravityMult);
+ }
+ }
+ else
+ {
+ // TODO*: Give user feedback about the missing data?
+ gObjectList.onPhysicsFlagsFetchFailure(objectId);
+ }
+ }
+
+}
+
void LLViewerObjectList::fetchPhysicsFlags()
{
// issue http request for stale object physics flags
@@ -1232,41 +1121,8 @@ void LLViewerObjectList::fetchPhysicsFlags()
if (!url.empty())
{
- LLSD id_list;
- U32 object_index = 0;
-
- for (
- std::set<LLUUID>::iterator iter = mStalePhysicsFlags.begin();
- iter != mStalePhysicsFlags.end();
- )
- {
- // Check to see if a request for this object
- // has already been made.
- if ( mPendingPhysicsFlags.find(*iter) ==
- mPendingPhysicsFlags.end() )
- {
- mPendingPhysicsFlags.insert(*iter);
- id_list[object_index++] = *iter;
- }
-
- mStalePhysicsFlags.erase(iter++);
-
- if (object_index >= MAX_CONCURRENT_PHYSICS_REQUESTS)
- {
- break;
- }
- }
-
- if ( id_list.size() > 0 )
- {
- LLSD post_data = LLSD::emptyMap();
-
- post_data["object_ids"] = id_list;
- LLHTTPClient::post(
- url,
- post_data,
- new LLPhysicsFlagsResponder(id_list));
- }
+ LLCoros::instance().launch("LLViewerObjectList::fetchPhisicsFlagsCoro",
+ boost::bind(&LLViewerObjectList::fetchPhisicsFlagsCoro, this, url));
}
else
{
@@ -1277,6 +1133,109 @@ void LLViewerObjectList::fetchPhysicsFlags()
}
}
+/*static*/
+void LLViewerObjectList::reportPhysicsFlagFailure(LLSD &objectList)
+{
+ // TODO*: No more hard coding
+ for (LLSD::array_iterator it = objectList.beginArray(); it != objectList.endArray(); ++it)
+ {
+ gObjectList.onPhysicsFlagsFetchFailure(it->asUUID());
+ }
+}
+
+void LLViewerObjectList::fetchPhisicsFlagsCoro(std::string url)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("genericPostCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLSD idList;
+ U32 objectIndex = 0;
+
+ for (std::set<LLUUID>::iterator it = mStalePhysicsFlags.begin(); it != mStalePhysicsFlags.end(); )
+ {
+ // Check to see if a request for this object
+ // has already been made.
+ if (mPendingPhysicsFlags.find(*it) == mPendingPhysicsFlags.end())
+ {
+ mPendingPhysicsFlags.insert(*it);
+ idList[objectIndex++] = *it;
+ }
+
+ mStalePhysicsFlags.erase(it++);
+
+ if (objectIndex >= MAX_CONCURRENT_PHYSICS_REQUESTS)
+ {
+ break;
+ }
+ }
+
+ if (idList.size() < 1)
+ {
+ LL_INFOS() << "No outstanding object physics flags to request." << LL_ENDL;
+ return;
+ }
+
+ LLSD postData = LLSD::emptyMap();
+
+ postData["object_ids"] = idList;
+
+ LLSD result = httpAdapter->postAndYield(httpRequest, url, postData);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status || result.has("error"))
+ {
+ if (result.has("error"))
+ {
+ LL_WARNS() << "Application level error when fetching object "
+ << "physics flags. Message: " << result["error"]["message"].asString()
+ << ", identifier: " << result["error"]["identifier"].asString()
+ << LL_ENDL;
+
+ // TODO*: Adaptively adjust request size if the
+ // service says we've requested too many and retry
+ }
+ reportPhysicsFlagFailure(idList);
+
+ return;
+ }
+
+ // Success, grab the resource cost and linked set costs
+ // for an object if one was returned
+ for (LLSD::array_iterator it = idList.beginArray(); it != idList.endArray(); ++it)
+ {
+ LLUUID objectId = it->asUUID();
+
+ // Check to see if the request contains data for the object
+ if (result.has(it->asString()))
+ {
+ const LLSD& data = result[it->asString()];
+
+ S32 shapeType = data["PhysicsShapeType"].asInteger();
+
+ gObjectList.updatePhysicsShapeType(objectId, shapeType);
+
+ if (data.has("Density"))
+ {
+ F32 density = data["Density"].asReal();
+ F32 friction = data["Friction"].asReal();
+ F32 restitution = data["Restitution"].asReal();
+ F32 gravityMult = data["GravityMultiplier"].asReal();
+
+ gObjectList.updatePhysicsProperties(objectId, density,
+ friction, restitution, gravityMult);
+ }
+ }
+ else
+ {
+ // TODO*: Give user feedback about the missing data?
+ gObjectList.onPhysicsFlagsFetchFailure(objectId);
+ }
+ }
+}
void LLViewerObjectList::clearDebugText()
{
diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h
index 594317cd9f..9ec7c4bc22 100755
--- a/indra/newview/llviewerobjectlist.h
+++ b/indra/newview/llviewerobjectlist.h
@@ -36,6 +36,8 @@
// project includes
#include "llviewerobject.h"
+#include "lleventcoro.h"
+#include "llcoros.h"
class LLCamera;
class LLNetMap;
@@ -227,6 +229,14 @@ protected:
std::set<LLViewerObject *> mSelectPickList;
friend class LLViewerObject;
+
+private:
+ static void reportObjectCostFailure(LLSD &objectList);
+ void fetchObjectCostsCoro(std::string url);
+
+ static void reportPhysicsFlagFailure(LLSD &obejectList);
+ void fetchPhisicsFlagsCoro(std::string url);
+
};
diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp
index 37b249dddd..828271da7a 100755
--- a/indra/newview/llviewerparcelmedia.cpp
+++ b/indra/newview/llviewerparcelmedia.cpp
@@ -43,6 +43,7 @@
//#include "llfirstuse.h"
#include "llpluginclassmedia.h"
#include "llviewertexture.h"
+#include "llcorehttputil.h"
// Static Variables
@@ -457,6 +458,7 @@ void LLViewerParcelMedia::processParcelMediaUpdate( LLMessageSystem *msg, void *
}
// Static
/////////////////////////////////////////////////////////////////////////////////////////
+// *TODO: I can not find any active code where this method is called...
void LLViewerParcelMedia::sendMediaNavigateMessage(const std::string& url)
{
std::string region_url = gAgent.getRegion()->getCapability("ParcelNavigateMedia");
@@ -467,7 +469,9 @@ void LLViewerParcelMedia::sendMediaNavigateMessage(const std::string& url)
body["agent-id"] = gAgent.getID();
body["local-id"] = LLViewerParcelMgr::getInstance()->getAgentParcel()->getLocalID();
body["url"] = url;
- LLHTTPClient::post(region_url, body, new LLHTTPClient::Responder);
+
+ LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(region_url, body,
+ "Media Navigation sent to sim.", "Media Navigation failed to send to sim.");
}
else
{
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index 59f57c218e..0fa6c432db 100755
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -67,6 +67,7 @@
#include "roles_constants.h"
#include "llweb.h"
#include "llvieweraudio.h"
+#include "llcorehttputil.h"
const F32 PARCEL_COLLISION_DRAW_SECS = 1.f;
@@ -1286,10 +1287,13 @@ const std::string& LLViewerParcelMgr::getAgentParcelName() const
void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel, bool use_agent_region)
{
- if(!parcel) return;
+ if(!parcel)
+ return;
LLViewerRegion *region = use_agent_region ? gAgent.getRegion() : LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
- if (!region) return;
+ if (!region)
+ return;
+
//LL_INFOS() << "found region: " << region->getName() << LL_ENDL;
LLSD body;
@@ -1302,7 +1306,9 @@ void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel, bool use_ag
parcel->packMessage(body);
LL_INFOS() << "Sending parcel properties update via capability to: "
<< url << LL_ENDL;
- LLHTTPClient::post(url, body, new LLHTTPClient::Responder());
+
+ LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, body,
+ "Parcel Properties sent to sim.", "Parcel Properties failed to send to sim.");
}
else
{
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index ec28461201..291af28bc3 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -48,7 +48,6 @@
#include "llavatarrenderinfoaccountant.h"
#include "llcallingcard.h"
#include "llcaphttpsender.h"
-#include "llcapabilitylistener.h"
#include "llcommandhandler.h"
#include "lldir.h"
#include "lleventpoll.h"
@@ -78,6 +77,9 @@
#include "llviewerdisplay.h"
#include "llviewerwindow.h"
#include "llprogressview.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
+#include "llcorehttputil.h"
#ifdef LL_WINDOWS
#pragma warning(disable:4355)
@@ -92,7 +94,6 @@
// We want to allow for seed cap retry, but its not useful after that 60 seconds.
// Give it 3 chances, each at 18 seconds to give ourselves a few seconds to connect anyways if we give up.
const S32 MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN = 3;
-const F32 CAP_REQUEST_TIMEOUT = 18;
// Even though we gave up on login, keep trying for caps after we are logged in:
const S32 MAX_CAP_REQUEST_ATTEMPTS = 30;
const U32 DEFAULT_MAX_REGION_WIDE_PRIM_COUNT = 15000;
@@ -105,31 +106,62 @@ typedef std::map<std::string, std::string> CapabilityMap;
static void log_capabilities(const CapabilityMap &capmap);
-class LLViewerRegionImpl {
+// support for secondlife:///app/region/{REGION} SLapps
+// N.B. this is defined to work exactly like the classic secondlife://{REGION}
+// However, the later syntax cannot support spaces in the region name because
+// spaces (and %20 chars) are illegal in the hostname of an http URL. Some
+// browsers let you get away with this, but some do not (such as Qt's Webkit).
+// Hence we introduced the newer secondlife:///app/region alternative.
+class LLRegionHandler : public LLCommandHandler
+{
+public:
+ // requests will be throttled from a non-trusted browser
+ LLRegionHandler() : LLCommandHandler("region", UNTRUSTED_THROTTLE) {}
+
+ bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
+ {
+ // make sure that we at least have a region name
+ int num_params = params.size();
+ if (num_params < 1)
+ {
+ return false;
+ }
+
+ // build a secondlife://{PLACE} SLurl from this SLapp
+ std::string url = "secondlife://";
+ for (int i = 0; i < num_params; i++)
+ {
+ if (i > 0)
+ {
+ url += "/";
+ }
+ url += params[i].asString();
+ }
+
+ // Process the SLapp as if it was a secondlife://{PLACE} SLurl
+ LLURLDispatcher::dispatch(url, "clicked", web, true);
+ return true;
+ }
+
+};
+LLRegionHandler gRegionHandler;
+
+
+class LLViewerRegionImpl
+{
public:
- LLViewerRegionImpl(LLViewerRegion * region, LLHost const & host)
- : mHost(host),
- mCompositionp(NULL),
- mEventPoll(NULL),
- mSeedCapMaxAttempts(MAX_CAP_REQUEST_ATTEMPTS),
- mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN),
- mSeedCapAttempts(0),
- mHttpResponderID(0),
- mLastCameraUpdate(0),
- mLastCameraOrigin(),
- mVOCachePartition(NULL),
- mLandp(NULL),
- // I'd prefer to set the LLCapabilityListener name to match the region
- // name -- it's disappointing that's not available at construction time.
- // We could instead store an LLCapabilityListener*, making
- // setRegionNameAndZone() replace the instance. Would that pose
- // consistency problems? Can we even request a capability before calling
- // setRegionNameAndZone()?
- // For testability -- the new Michael Feathers paradigm --
- // LLCapabilityListener binds all the globals it expects to need at
- // construction time.
- mCapabilityListener(host.getString(), gMessageSystem, *region,
- gAgent.getID(), gAgent.getSessionID())
+ LLViewerRegionImpl(LLViewerRegion * region, LLHost const & host):
+ mHost(host),
+ mCompositionp(NULL),
+ mEventPoll(NULL),
+ mSeedCapMaxAttempts(MAX_CAP_REQUEST_ATTEMPTS),
+ mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN),
+ mSeedCapAttempts(0),
+ mHttpResponderID(0),
+ mLastCameraUpdate(0),
+ mLastCameraOrigin(),
+ mVOCachePartition(NULL),
+ mLandp(NULL)
{}
void buildCapabilityNames(LLSD& capabilityNames);
@@ -181,220 +213,284 @@ public:
S32 mHttpResponderID;
- /// Post an event to this LLCapabilityListener to invoke a capability message on
- /// this LLViewerRegion's server
- /// (https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes#Capabilities)
- LLCapabilityListener mCapabilityListener;
-
//spatial partitions for objects in this region
std::vector<LLViewerOctreePartition*> mObjectPartition;
- LLVector3 mLastCameraOrigin;
- U32 mLastCameraUpdate;
-};
-
-// support for secondlife:///app/region/{REGION} SLapps
-// N.B. this is defined to work exactly like the classic secondlife://{REGION}
-// However, the later syntax cannot support spaces in the region name because
-// spaces (and %20 chars) are illegal in the hostname of an http URL. Some
-// browsers let you get away with this, but some do not (such as Qt's Webkit).
-// Hence we introduced the newer secondlife:///app/region alternative.
-class LLRegionHandler : public LLCommandHandler
-{
-public:
- // requests will be throttled from a non-trusted browser
- LLRegionHandler() : LLCommandHandler("region", UNTRUSTED_THROTTLE) {}
-
- bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
- {
- // make sure that we at least have a region name
- int num_params = params.size();
- if (num_params < 1)
- {
- return false;
- }
-
- // build a secondlife://{PLACE} SLurl from this SLapp
- std::string url = "secondlife://";
- for (int i = 0; i < num_params; i++)
- {
- if (i > 0)
- {
- url += "/";
- }
- url += params[i].asString();
- }
+ LLVector3 mLastCameraOrigin;
+ U32 mLastCameraUpdate;
- // Process the SLapp as if it was a secondlife://{PLACE} SLurl
- LLURLDispatcher::dispatch(url, "clicked", web, true);
- return true;
- }
+ void requestBaseCapabilitiesCoro(U64 regionHandle);
+ void requestBaseCapabilitiesCompleteCoro(U64 regionHandle);
+ void requestSimulatorFeatureCoro(std::string url, U64 regionHandle);
};
-LLRegionHandler gRegionHandler;
-class BaseCapabilitiesComplete : public LLHTTPClient::Responder
+void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
{
- LOG_CLASS(BaseCapabilitiesComplete);
-public:
- BaseCapabilitiesComplete(U64 region_handle, S32 id)
- : mRegionHandle(region_handle), mID(id)
- { }
- virtual ~BaseCapabilitiesComplete()
- { }
-
- static BaseCapabilitiesComplete* build( U64 region_handle, S32 id )
- {
- return new BaseCapabilitiesComplete(region_handle, id);
- }
-
-private:
- /* virtual */void httpFailure()
- {
- LL_WARNS("AppInit", "Capabilities") << dumpResponse() << LL_ENDL;
- LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
- if (regionp)
- {
- regionp->failedSeedCapability();
- }
- }
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("BaseCapabilitiesRequest", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- /* virtual */ void httpSuccess()
- {
- LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
- if(!regionp) //region was removed
- {
- LL_WARNS("AppInit", "Capabilities") << "Received results for region that no longer exists!" << LL_ENDL;
- return ;
- }
- if( mID != regionp->getHttpResponderID() ) // region is no longer referring to this responder
- {
- LL_WARNS("AppInit", "Capabilities") << "Received results for a stale http responder!" << LL_ENDL;
- regionp->failedSeedCapability();
- 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);
+ LLSD result;
+ LLViewerRegion *regionp = NULL;
- LL_DEBUGS("AppInit", "Capabilities")
- << "Capability '" << iter->first << "' is '" << iter->second << "'" << LL_ENDL;
-
- /* HACK we're waiting for the ServerReleaseNotes */
- if (iter->first == "ServerReleaseNotes" && regionp->getReleaseNotesRequested())
- {
- regionp->showReleaseNotes();
- }
- }
-
- regionp->setCapabilitiesReceived(true);
+ // This loop is used for retrying a capabilities request.
+ do
+ {
+ regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+ if (!regionp) //region was removed
+ {
+ LL_WARNS("AppInit", "Capabilities") << "Attempting to get capabilities for region that no longer exists!" << LL_ENDL;
+ return; // this error condition is not recoverable.
+ }
+
+ std::string url = regionp->getCapability("Seed");
+ if (url.empty())
+ {
+ LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities, and can not determine url!" << LL_ENDL;
+ return; // this error condition is not recoverable.
+ }
+
+ // After a few attempts, continue login. But keep trying to get the caps:
+ if (mSeedCapAttempts >= mSeedCapMaxAttemptsBeforeLogin &&
+ STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
+ {
+ LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED);
+ }
+
+ if (mSeedCapAttempts > mSeedCapMaxAttempts)
+ {
+ // *TODO: Give a user pop-up about this error?
+ LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities from '" << url << "' after " << mSeedCapAttempts << " attempts. Giving up!" << LL_ENDL;
+ return; // this error condition is not recoverable.
+ }
+
+ S32 id = ++mHttpResponderID;
+ ++mSeedCapAttempts;
+
+ LLSD capabilityNames = LLSD::emptyArray();
+ buildCapabilityNames(capabilityNames);
+
+ LL_INFOS("AppInit", "Capabilities") << "Requesting seed from " << url
+ << " (attempt #" << mSeedCapAttempts << ")" << LL_ENDL;
+
+ regionp = NULL;
+ result = httpAdapter->postAndYield(httpRequest, url, capabilityNames);
+
+ regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+ if (!regionp) //region was removed
+ {
+ LL_WARNS("AppInit", "Capabilities") << "Received capabilities for region that no longer exists!" << LL_ENDL;
+ return; // this error condition is not recoverable.
+ }
+
+ if (id != mHttpResponderID) // region is no longer referring to this request
+ {
+ LL_WARNS("AppInit", "Capabilities") << "Received results for a stale capabilities request!" << LL_ENDL;
+ // setup for retry.
+ continue;
+ }
+
+ LLSD httpResults = result["http_result"];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+ if (!status)
+ {
+ LL_WARNS("AppInit", "Capabilities") << "HttpStatus error " << LL_ENDL;
+ // setup for retry.
+ continue;
+ }
+
+ // remove the http_result from the llsd
+ result.erase("http_result");
+
+ LLSD::map_const_iterator iter;
+ for (iter = result.beginMap(); iter != result.endMap(); ++iter)
+ {
+ regionp->setCapability(iter->first, iter->second);
+
+ LL_DEBUGS("AppInit", "Capabilities")
+ << "Capability '" << iter->first << "' is '" << iter->second << "'" << LL_ENDL;
+ }
+
+ regionp->setCapabilitiesReceived(true);
+
+ if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
+ {
+ LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED);
+ }
+
+ break;
+ }
+ while (true);
+
+ if (regionp && regionp->isCapabilityAvailable("ServerReleaseNotes") &&
+ regionp->getReleaseNotesRequested())
+ { // *HACK: we're waiting for the ServerReleaseNotes
+ regionp->showReleaseNotes();
+ }
- if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
- {
- LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED );
- }
- }
+}
-private:
- U64 mRegionHandle;
- S32 mID;
-};
-class BaseCapabilitiesCompleteTracker : public LLHTTPClient::Responder
+void LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro(U64 regionHandle)
{
- LOG_CLASS(BaseCapabilitiesCompleteTracker);
-public:
- BaseCapabilitiesCompleteTracker( U64 region_handle)
- : mRegionHandle(region_handle)
- { }
-
- virtual ~BaseCapabilitiesCompleteTracker()
- { }
-
- static BaseCapabilitiesCompleteTracker* build( U64 region_handle )
- {
- return new BaseCapabilitiesCompleteTracker( region_handle );
- }
-
-private:
- /* virtual */ void httpFailure()
- {
- LL_WARNS() << dumpResponse() << LL_ENDL;
- }
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("BaseCapabilitiesRequest", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- /* virtual */ void httpSuccess()
- {
- LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
- if( !regionp )
- {
- LL_WARNS("AppInit", "Capabilities") << "Received results for region that no longer exists!" << LL_ENDL;
- return ;
- }
+ LLSD result;
+ LLViewerRegion *regionp = NULL;
- 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->setCapabilityDebug(iter->first, iter->second);
- //LL_INFOS()<<"BaseCapabilitiesCompleteTracker New Caps "<<iter->first<<" "<< iter->second<<LL_ENDL;
- }
-
- if ( regionp->getRegionImpl()->mCapabilities.size() != regionp->getRegionImpl()->mSecondCapabilitiesTracker.size() )
- {
- LL_WARNS("AppInit", "Capabilities")
- << "Sim sent duplicate base caps that differ in size from what we initially received - most likely content. "
- << "mCapabilities == " << regionp->getRegionImpl()->mCapabilities.size()
- << " mSecondCapabilitiesTracker == " << regionp->getRegionImpl()->mSecondCapabilitiesTracker.size()
- << LL_ENDL;
+ // This loop is used for retrying a capabilities request.
+ do
+ {
+ regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+ if (!regionp) //region was removed
+ {
+ LL_WARNS("AppInit", "Capabilities") << "Attempting to get capabilities for region that no longer exists!" << LL_ENDL;
+ break; // this error condition is not recoverable.
+ }
+
+ std::string url = regionp->getCapabilityDebug("Seed");
+ if (url.empty())
+ {
+ LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities, and can not determine url!" << LL_ENDL;
+ break; // this error condition is not recoverable.
+ }
+
+ LLSD capabilityNames = LLSD::emptyArray();
+ buildCapabilityNames(capabilityNames);
+
+ LL_INFOS("AppInit", "Capabilities") << "Requesting second Seed from " << url << LL_ENDL;
+
+ regionp = NULL;
+ result = httpAdapter->postAndYield(httpRequest, url, capabilityNames);
+
+ LLSD httpResults = result["http_result"];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+ if (!status)
+ {
+ LL_WARNS("AppInit", "Capabilities") << "HttpStatus error " << LL_ENDL;
+ break; // no retry
+ }
+
+ regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+ if (!regionp) //region was removed
+ {
+ LL_WARNS("AppInit", "Capabilities") << "Received capabilities for region that no longer exists!" << LL_ENDL;
+ break; // this error condition is not recoverable.
+ }
+
+ // remove the http_result from the llsd
+ result.erase("http_result");
+
+ LLSD::map_const_iterator iter;
+ for (iter = result.beginMap(); iter != result.endMap(); ++iter)
+ {
+ regionp->setCapabilityDebug(iter->first, iter->second);
+ //LL_INFOS()<<"BaseCapabilitiesCompleteTracker New Caps "<<iter->first<<" "<< iter->second<<LL_ENDL;
+ }
+
+ if (mCapabilities.size() != mSecondCapabilitiesTracker.size())
+ {
+ LL_WARNS("AppInit", "Capabilities")
+ << "Sim sent duplicate base caps that differ in size from what we initially received - most likely content. "
+ << "mCapabilities == " << mCapabilities.size()
+ << " mSecondCapabilitiesTracker == " << mSecondCapabilitiesTracker.size()
+ << LL_ENDL;
#ifdef DEBUG_CAPS_GRANTS
- LL_WARNS("AppInit", "Capabilities")
- << "Initial Base capabilities: " << LL_ENDL;
+ LL_WARNS("AppInit", "Capabilities")
+ << "Initial Base capabilities: " << LL_ENDL;
- log_capabilities(regionp->getRegionImpl()->mCapabilities);
+ log_capabilities(mCapabilities);
- LL_WARNS("AppInit", "Capabilities")
- << "Latest base capabilities: " << LL_ENDL;
+ LL_WARNS("AppInit", "Capabilities")
+ << "Latest base capabilities: " << LL_ENDL;
- log_capabilities(regionp->getRegionImpl()->mSecondCapabilitiesTracker);
+ log_capabilities(mSecondCapabilitiesTracker);
#endif
- if (regionp->getRegionImpl()->mSecondCapabilitiesTracker.size() > regionp->getRegionImpl()->mCapabilities.size() )
- {
- // *HACK Since we were granted more base capabilities in this grant request than the initial, replace
- // the old with the new. This shouldn't happen i.e. we should always get the same capabilities from a
- // sim. The simulator fix from SH-3895 should prevent it from happening, at least in the case of the
- // inventory api capability grants.
-
- // Need to clear a std::map before copying into it because old keys take precedence.
- regionp->getRegionImplNC()->mCapabilities.clear();
- regionp->getRegionImplNC()->mCapabilities = regionp->getRegionImpl()->mSecondCapabilitiesTracker;
- }
- }
- else
- {
- LL_DEBUGS("CrossingCaps") << "Sim sent multiple base cap grants with matching sizes." << LL_ENDL;
- }
- regionp->getRegionImplNC()->mSecondCapabilitiesTracker.clear();
- }
+ if (mSecondCapabilitiesTracker.size() > mCapabilities.size())
+ {
+ // *HACK Since we were granted more base capabilities in this grant request than the initial, replace
+ // the old with the new. This shouldn't happen i.e. we should always get the same capabilities from a
+ // sim. The simulator fix from SH-3895 should prevent it from happening, at least in the case of the
+ // inventory api capability grants.
+ // Need to clear a std::map before copying into it because old keys take precedence.
+ mCapabilities.clear();
+ mCapabilities = mSecondCapabilitiesTracker;
+ }
+ }
+ else
+ {
+ LL_DEBUGS("CrossingCaps") << "Sim sent multiple base cap grants with matching sizes." << LL_ENDL;
+ }
+ mSecondCapabilitiesTracker.clear();
+ }
+ while (false);
-private:
- U64 mRegionHandle;
-};
+}
+
+void LLViewerRegionImpl::requestSimulatorFeatureCoro(std::string url, U64 regionHandle)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("BaseCapabilitiesRequest", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLViewerRegion *regionp = NULL;
+ S32 attemptNumber = 0;
+ // This loop is used for retrying a capabilities request.
+ do
+ {
+ ++attemptNumber;
+
+ if (attemptNumber > MAX_CAP_REQUEST_ATTEMPTS)
+ {
+ LL_WARNS("AppInit", "SimulatorFeatures") << "Retries count exceeded attempting to get Simulator feature from "
+ << url << LL_ENDL;
+ break;
+ }
+
+ regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+ if (!regionp) //region was removed
+ {
+ LL_WARNS("AppInit", "SimulatorFeatures") << "Attempting to request Sim Feature for region that no longer exists!" << LL_ENDL;
+ break; // this error condition is not recoverable.
+ }
+
+ regionp = NULL;
+ LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+ LLSD httpResults = result["http_result"];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+ if (!status)
+ {
+ LL_WARNS("AppInit", "SimulatorFeatures") << "HttpStatus error retrying" << LL_ENDL;
+ continue;
+ }
+
+ // remove the http_result from the llsd
+ result.erase("http_result");
+
+ regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
+ if (!regionp) //region was removed
+ {
+ LL_WARNS("AppInit", "SimulatorFeatures") << "Attempting to set Sim Feature for region that no longer exists!" << LL_ENDL;
+ break; // this error condition is not recoverable.
+ }
+
+ regionp->setSimulatorFeatures(result);
+
+ break;
+ }
+ while (true);
+
+}
LLViewerRegion::LLViewerRegion(const U64 &handle,
const LLHost &host,
@@ -525,11 +621,6 @@ LLViewerRegion::~LLViewerRegion()
mImpl = NULL;
}
-LLEventPump& LLViewerRegion::getCapAPI() const
-{
- return mImpl->mCapabilityListener.getCapAPI();
-}
-
/*virtual*/
const LLHost& LLViewerRegion::getHost() const
{
@@ -2810,15 +2901,14 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
if (getCapability("Seed") == url)
{
setCapabilityDebug("Seed", url);
- LL_DEBUGS("CrossingCaps") << "Received duplicate seed capability, posting to seed " <<
+ LL_WARNS("CrossingCaps") << "Received duplicate seed capability, posting to seed " <<
url << LL_ENDL;
//Instead of just returning we build up a second set of seed caps and compare them
//to the "original" seed cap received and determine why there is problem!
- LLSD capabilityNames = LLSD::emptyArray();
- mImpl->buildCapabilityNames( capabilityNames );
- LLHTTPClient::post( url, capabilityNames, BaseCapabilitiesCompleteTracker::build(getHandle() ),
- LLSD(), CAP_REQUEST_TIMEOUT );
+ std::string coroname =
+ LLCoros::instance().launch("LLEnvironmentRequest::requestBaseCapabilitiesCompleteCoro",
+ boost::bind(&LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro, mImpl, getHandle()));
return;
}
@@ -2828,15 +2918,11 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
mImpl->mCapabilities.clear();
setCapability("Seed", url);
- LLSD capabilityNames = LLSD::emptyArray();
- mImpl->buildCapabilityNames(capabilityNames);
-
- LL_INFOS() << "posting to seed " << url << LL_ENDL;
+ std::string coroname =
+ LLCoros::instance().launch("LLViewerRegionImpl::requestBaseCapabilitiesCoro",
+ boost::bind(&LLViewerRegionImpl::requestBaseCapabilitiesCoro, mImpl, getHandle()));
- S32 id = ++mImpl->mHttpResponderID;
- LLHTTPClient::post(url, capabilityNames,
- BaseCapabilitiesComplete::build(getHandle(), id),
- LLSD(), CAP_REQUEST_TIMEOUT);
+ LL_INFOS("AppInit", "Capabilities") << "Launching " << coroname << " requesting seed capabilities from " << url << LL_ENDL;
}
S32 LLViewerRegion::getNumSeedCapRetries()
@@ -2844,94 +2930,6 @@ S32 LLViewerRegion::getNumSeedCapRetries()
return mImpl->mSeedCapAttempts;
}
-void LLViewerRegion::failedSeedCapability()
-{
- // Should we retry asking for caps?
- mImpl->mSeedCapAttempts++;
- std::string url = getCapability("Seed");
- if ( url.empty() )
- {
- LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities, and can not determine url for retries!" << LL_ENDL;
- return;
- }
- // After a few attempts, continue login. We will keep trying once in-world:
- if ( mImpl->mSeedCapAttempts >= mImpl->mSeedCapMaxAttemptsBeforeLogin &&
- STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState() )
- {
- LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED );
- }
-
- if ( mImpl->mSeedCapAttempts < mImpl->mSeedCapMaxAttempts)
- {
- LLSD capabilityNames = LLSD::emptyArray();
- mImpl->buildCapabilityNames(capabilityNames);
-
- LL_INFOS() << "posting to seed " << url << " (retry "
- << mImpl->mSeedCapAttempts << ")" << LL_ENDL;
-
- S32 id = ++mImpl->mHttpResponderID;
- LLHTTPClient::post(url, capabilityNames,
- BaseCapabilitiesComplete::build(getHandle(), id),
- LLSD(), CAP_REQUEST_TIMEOUT);
- }
- else
- {
- // *TODO: Give a user pop-up about this error?
- LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities from '" << url << "' after " << mImpl->mSeedCapAttempts << " attempts. Giving up!" << LL_ENDL;
- }
-}
-
-class SimulatorFeaturesReceived : public LLHTTPClient::Responder
-{
- LOG_CLASS(SimulatorFeaturesReceived);
-public:
- 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)
- { }
-
- /* virtual */ void httpFailure()
- {
- LL_WARNS("AppInit", "SimulatorFeatures") << dumpResponse() << LL_ENDL;
- retry();
- }
-
- /* virtual */ void httpSuccess()
- {
- LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
- if(!regionp) //region is removed or responder is not created.
- {
- LL_WARNS("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);
- }
-
- void retry()
- {
- if (mAttempt < mMaxAttempts)
- {
- mAttempt++;
- LL_WARNS("AppInit", "SimulatorFeatures") << "Re-trying '" << mRetryURL << "'. Retry #" << mAttempt << LL_ENDL;
- LLHTTPClient::get(mRetryURL, new SimulatorFeaturesReceived(*this), LLSD(), CAP_REQUEST_TIMEOUT);
- }
- }
-
- std::string mRetryURL;
- U64 mRegionHandle;
- S32 mAttempt;
- S32 mMaxAttempts;
-};
-
-
void LLViewerRegion::setCapability(const std::string& name, const std::string& url)
{
if(name == "EventQueueGet")
@@ -2947,7 +2945,11 @@ void LLViewerRegion::setCapability(const std::string& name, const std::string& u
else if (name == "SimulatorFeatures")
{
// kick off a request for simulator features
- LLHTTPClient::get(url, new SimulatorFeaturesReceived(url, getHandle()), LLSD(), CAP_REQUEST_TIMEOUT);
+ std::string coroname =
+ LLCoros::instance().launch("LLViewerRegionImpl::requestSimulatorFeatureCoro",
+ boost::bind(&LLViewerRegionImpl::requestSimulatorFeatureCoro, mImpl, url, getHandle()));
+
+ LL_INFOS("AppInit", "SimulatorFeatures") << "Launching " << coroname << " requesting simulator features from " << url << LL_ENDL;
}
else
{
@@ -2970,9 +2972,20 @@ void LLViewerRegion::setCapabilityDebug(const std::string& name, const std::stri
mHttpUrl = url ;
}
}
+}
+std::string LLViewerRegion::getCapabilityDebug(const std::string& name) const
+{
+ CapabilityMap::const_iterator iter = mImpl->mSecondCapabilitiesTracker.find(name);
+ if (iter == mImpl->mSecondCapabilitiesTracker.end())
+ {
+ return "";
+ }
+
+ return iter->second;
}
+
bool LLViewerRegion::isSpecialCapabilityName(const std::string &name)
{
return name == "EventQueueGet" || name == "UntrustedSimulatorMessage";
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index c14fa5aee8..8c4966369c 100755
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -40,7 +40,6 @@
#include "llweb.h"
#include "llcapabilityprovider.h"
#include "m4math.h" // LLMatrix4
-#include "llhttpclient.h"
#include "llframetimer.h"
// Surface id's
@@ -62,7 +61,6 @@ class LLVOCache;
class LLVOCacheEntry;
class LLSpatialPartition;
class LLEventPump;
-class LLCapabilityListener;
class LLDataPacker;
class LLDataPackerBinaryBuffer;
class LLHost;
@@ -253,13 +251,14 @@ public:
// Get/set named capability URLs for this region.
void setSeedCapability(const std::string& url);
- void failedSeedCapability();
S32 getNumSeedCapRetries();
void setCapability(const std::string& name, const std::string& url);
void setCapabilityDebug(const std::string& name, const std::string& url);
bool isCapabilityAvailable(const std::string& name) const;
// implements LLCapabilityProvider
virtual std::string getCapability(const std::string& name) const;
+ std::string getCapabilityDebug(const std::string& name) const;
+
// has region received its final (not seed) capability list?
bool capabilitiesReceived() const;
@@ -269,10 +268,6 @@ public:
static bool isSpecialCapabilityName(const std::string &name);
void logActiveCapabilities() const;
- /// Get LLEventPump on which we listen for capability requests
- /// (https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes#Capabilities)
- LLEventPump& getCapAPI() const;
-
/// implements LLCapabilityProvider
/*virtual*/ const LLHost& getHost() const;
const U64 &getHandle() const { return mHandle; }
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index f60829e9e8..2c3067cd3a 100755
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -60,6 +60,7 @@
#include "llfeaturemanager.h"
#include "llviewernetwork.h"
#include "llmeshrepository.h" //for LLMeshRepository::sBytesReceived
+#include "llcorehttputil.h"
namespace LLStatViewer
{
@@ -410,24 +411,6 @@ void update_statistics()
}
}
-class ViewerStatsResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(ViewerStatsResponder);
-public:
- ViewerStatsResponder() { }
-
-private:
- /* virtual */ void httpFailure()
- {
- LL_WARNS() << dumpResponse() << LL_ENDL;
- }
-
- /* virtual */ void httpSuccess()
- {
- LL_INFOS() << "OK" << LL_ENDL;
- }
-};
-
/*
* The sim-side LLSD is in newsim/llagentinfo.cpp:forwardViewerStats.
*
@@ -618,8 +601,8 @@ void send_stats()
body["MinimalSkin"] = false;
LLViewerStats::getInstance()->addToMessage(body);
- LLHTTPClient::post(url, body, new ViewerStatsResponder());
-
+ LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, body,
+ "Statistics posted to sim", "Failed to post statistics to sim");
LLViewerStats::instance().getRecording().resume();
}
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index c1ca0aed69..fb2171ccc2 100755
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -65,6 +65,7 @@
#include "llsdutil.h"
#include "llstartup.h"
#include "llsdserialize.h"
+#include "llcorehttputil.h"
#if LL_MSVC
// disable boost::lexical_cast warning
@@ -106,6 +107,9 @@ void selfClearPhases()
using namespace LLAvatarAppearanceDefines;
+
+LLSD summarize_by_buckets(std::vector<LLSD> in_records, std::vector<std::string> by_fields, std::string val_field);
+
/*********************************************************************************
** **
** Begin private LLVOAvatarSelf Support classes
@@ -128,25 +132,6 @@ struct LocalTextureData
LLTextureEntry *mTexEntry;
};
-// TODO - this class doesn't really do anything, could just use a base
-// class responder if nothing else gets added.
-class LLHoverHeightResponder: public LLHTTPClient::Responder
-{
-public:
- LLHoverHeightResponder(): LLHTTPClient::Responder() {}
-
-private:
- void httpFailure()
- {
- LL_WARNS() << dumpResponse() << LL_ENDL;
- }
-
- void httpSuccess()
- {
- LL_INFOS() << dumpResponse() << LL_ENDL;
- }
-};
-
//-----------------------------------------------------------------------------
// Callback data
//-----------------------------------------------------------------------------
@@ -181,7 +166,9 @@ LLVOAvatarSelf::LLVOAvatarSelf(const LLUUID& id,
mRegionCrossingCount(0),
// Value outside legal range, so will always be a mismatch the
// first time through.
- mLastHoverOffsetSent(LLVector3(0.0f, 0.0f, -999.0f))
+ mLastHoverOffsetSent(LLVector3(0.0f, 0.0f, -999.0f)),
+ mInitialMetric(true),
+ mMetricSequence(0)
{
mMotionController.mIsSelf = TRUE;
@@ -2164,43 +2151,76 @@ const std::string LLVOAvatarSelf::debugDumpAllLocalTextureDataInfo() const
return text;
}
-class ViewerAppearanceChangeMetricsResponder: public LLCurl::Responder
-{
- LOG_CLASS(ViewerAppearanceChangeMetricsResponder);
-public:
- ViewerAppearanceChangeMetricsResponder( S32 expected_sequence,
- volatile const S32 & live_sequence,
- volatile bool & reporting_started):
- mExpectedSequence(expected_sequence),
- mLiveSequence(live_sequence),
- mReportingStarted(reporting_started)
- {
- }
-
-private:
- /* virtual */ void httpSuccess()
- {
- LL_DEBUGS("Avatar") << "OK" << LL_ENDL;
-
- 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;
- volatile bool & mReportingStarted;
-};
+void LLVOAvatarSelf::appearanceChangeMetricsCoro(std::string url)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("appearanceChangeMetrics", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
+
+ S32 currentSequence = mMetricSequence;
+ if (S32_MAX == ++mMetricSequence)
+ mMetricSequence = 0;
+
+ LLSD msg;
+ msg["message"] = "ViewerAppearanceChangeMetrics";
+ msg["session_id"] = gAgentSessionID;
+ msg["agent_id"] = gAgentID;
+ msg["sequence"] = currentSequence;
+ msg["initial"] = mInitialMetric;
+ msg["break"] = false;
+ msg["duration"] = mTimeSinceLastRezMessage.getElapsedTimeF32();
+
+ // Status of our own rezzing.
+ msg["rez_status"] = LLVOAvatar::rezStatusToString(getRezzedStatus());
+
+ // Status of all nearby avs including ourself.
+ msg["nearby"] = LLSD::emptyArray();
+ std::vector<S32> rez_counts;
+ LLVOAvatar::getNearbyRezzedStats(rez_counts);
+ for (S32 rez_stat = 0; rez_stat < rez_counts.size(); ++rez_stat)
+ {
+ std::string rez_status_name = LLVOAvatar::rezStatusToString(rez_stat);
+ msg["nearby"][rez_status_name] = rez_counts[rez_stat];
+ }
+
+ // std::vector<std::string> bucket_fields("timer_name","is_self","grid_x","grid_y","is_using_server_bake");
+ std::vector<std::string> by_fields;
+ by_fields.push_back("timer_name");
+ by_fields.push_back("completed");
+ by_fields.push_back("grid_x");
+ by_fields.push_back("grid_y");
+ by_fields.push_back("is_using_server_bakes");
+ by_fields.push_back("is_self");
+ by_fields.push_back("central_bake_version");
+ LLSD summary = summarize_by_buckets(mPendingTimerRecords, by_fields, std::string("elapsed"));
+ msg["timers"] = summary;
+
+ mPendingTimerRecords.clear();
+
+ LL_DEBUGS("Avatar") << avString() << "message: " << ll_pretty_print_sd(msg) << LL_ENDL;
+
+ gPendingMetricsUploads++;
+
+ LLSD result = httpAdapter->postAndYield(httpRequest, url, msg);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ gPendingMetricsUploads--;
+
+ if (!status)
+ {
+ LL_WARNS("Avatar") << "Unable to upload statistics" << LL_ENDL;
+ return;
+ }
+ else
+ {
+ LL_INFOS("Avatar") << "Statistics upload OK" << LL_ENDL;
+ mInitialMetric = false;
+ }
+}
bool LLVOAvatarSelf::updateAvatarRezMetrics(bool force_send)
{
@@ -2278,51 +2298,7 @@ LLSD summarize_by_buckets(std::vector<LLSD> in_records,
void LLVOAvatarSelf::sendViewerAppearanceChangeMetrics()
{
- static volatile bool reporting_started(false);
- static volatile S32 report_sequence(0);
-
- LLSD msg;
- msg["message"] = "ViewerAppearanceChangeMetrics";
- msg["session_id"] = gAgentSessionID;
- msg["agent_id"] = gAgentID;
- msg["sequence"] = report_sequence;
- msg["initial"] = !reporting_started;
- msg["break"] = false;
- msg["duration"] = mTimeSinceLastRezMessage.getElapsedTimeF32();
-
- // Status of our own rezzing.
- msg["rez_status"] = LLVOAvatar::rezStatusToString(getRezzedStatus());
-
- // Status of all nearby avs including ourself.
- msg["nearby"] = LLSD::emptyArray();
- std::vector<S32> rez_counts;
- LLVOAvatar::getNearbyRezzedStats(rez_counts);
- for (S32 rez_stat=0; rez_stat < rez_counts.size(); ++rez_stat)
- {
- std::string rez_status_name = LLVOAvatar::rezStatusToString(rez_stat);
- msg["nearby"][rez_status_name] = rez_counts[rez_stat];
- }
-
- // std::vector<std::string> bucket_fields("timer_name","is_self","grid_x","grid_y","is_using_server_bake");
- std::vector<std::string> by_fields;
- by_fields.push_back("timer_name");
- by_fields.push_back("completed");
- by_fields.push_back("grid_x");
- by_fields.push_back("grid_y");
- by_fields.push_back("is_using_server_bakes");
- by_fields.push_back("is_self");
- by_fields.push_back("central_bake_version");
- LLSD summary = summarize_by_buckets(mPendingTimerRecords, by_fields, std::string("elapsed"));
- msg["timers"] = summary;
-
- mPendingTimerRecords.clear();
-
- // Update sequence number
- if (S32_MAX == ++report_sequence)
- report_sequence = 0;
-
- LL_DEBUGS("Avatar") << avString() << "message: " << ll_pretty_print_sd(msg) << LL_ENDL;
- std::string caps_url;
+ std::string caps_url;
if (getRegion())
{
// runway - change here to activate.
@@ -2330,13 +2306,9 @@ void LLVOAvatarSelf::sendViewerAppearanceChangeMetrics()
}
if (!caps_url.empty())
{
- gPendingMetricsUploads++;
- LLCurlRequest::headers_t headers;
- LLHTTPClient::post(caps_url,
- msg,
- new ViewerAppearanceChangeMetricsResponder(report_sequence,
- report_sequence,
- reporting_started));
+
+ LLCoros::instance().launch("LLVOAvatarSelf::appearanceChangeMetricsCoro",
+ boost::bind(&LLVOAvatarSelf::appearanceChangeMetricsCoro, this, caps_url));
mTimeSinceLastRezMessage.reset();
}
}
@@ -2759,8 +2731,12 @@ void LLVOAvatarSelf::sendHoverHeight() const
update["hover_height"] = hover_offset[2];
LL_DEBUGS("Avatar") << avString() << "sending hover height value " << hover_offset[2] << LL_ENDL;
- LLHTTPClient::post(url, update, new LLHoverHeightResponder);
+ // *TODO: - this class doesn't really do anything, could just use a base
+ // class responder if nothing else gets added.
+ // (comment from removed Responder)
+ LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, update,
+ "Hover hight sent to sim", "Hover hight not sent to sim");
mLastHoverOffsetSent = hover_offset;
}
}
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index 332a6353ad..5bdd662152 100755
--- a/indra/newview/llvoavatarself.h
+++ b/indra/newview/llvoavatarself.h
@@ -31,6 +31,8 @@
#include "llviewertexture.h"
#include "llvoavatar.h"
#include <map>
+#include "lleventcoro.h"
+#include "llcoros.h"
struct LocalTextureData;
class LLInventoryCallback;
@@ -393,6 +395,9 @@ private:
F32 mDebugBakedTextureTimes[LLAvatarAppearanceDefines::BAKED_NUM_INDICES][2]; // time to start upload and finish upload of each baked texture
void debugTimingLocalTexLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
+ void appearanceChangeMetricsCoro(std::string url);
+ bool mInitialMetric;
+ S32 mMetricSequence;
/** Diagnostics
** **
*******************************************************************************/
diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp
index 426ca332e4..192d50ae9b 100755
--- a/indra/newview/llvoicechannel.cpp
+++ b/indra/newview/llvoicechannel.cpp
@@ -28,7 +28,6 @@
#include "llagent.h"
#include "llfloaterreg.h"
-#include "llhttpclient.h"
#include "llimview.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
@@ -37,7 +36,7 @@
#include "llviewercontrol.h"
#include "llviewerregion.h"
#include "llvoicechannel.h"
-
+#include "llcorehttputil.h"
LLVoiceChannel::voice_channel_map_t LLVoiceChannel::sVoiceChannelMap;
LLVoiceChannel::voice_channel_map_uri_t LLVoiceChannel::sVoiceChannelURIMap;
@@ -52,71 +51,6 @@ BOOL LLVoiceChannel::sSuspended = FALSE;
//
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 httpFailure();
- virtual void httpSuccess();
-
-private:
- LLUUID mSessionID;
-};
-
-
-void LLVoiceCallCapResponder::httpFailure()
-{
- LL_WARNS("Voice") << dumpResponse() << LL_ENDL;
- LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(mSessionID);
- if ( channelp )
- {
- if ( HTTP_FORBIDDEN == getStatus() )
- {
- //403 == no ability
- LLNotificationsUtil::add(
- "VoiceNotAllowed",
- channelp->getNotifyArgs());
- }
- else
- {
- LLNotificationsUtil::add(
- "VoiceCallGenericError",
- channelp->getNotifyArgs());
- }
- channelp->deactivate();
- }
-}
-
-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)
- {
- LL_DEBUGS("Voice") << "LLVoiceCallCapResponder::result got "
- << iter->first << LL_ENDL;
- }
-
- channelp->setChannelInfo(
- content["voice_credentials"]["channel_uri"].asString(),
- content["voice_credentials"]["channel_credentials"].asString());
- }
-}
-
//
// LLVoiceChannel
//
@@ -545,12 +479,9 @@ void LLVoiceChannelGroup::getChannelInfo()
if (region)
{
std::string url = region->getCapability("ChatSessionRequest");
- LLSD data;
- data["method"] = "call";
- data["session-id"] = mSessionID;
- LLHTTPClient::post(url,
- data,
- new LLVoiceCallCapResponder(mSessionID));
+
+ LLCoros::instance().launch("LLVoiceChannelGroup::voiceCallCapCoro",
+ boost::bind(&LLVoiceChannelGroup::voiceCallCapCoro, this, url));
}
}
@@ -673,6 +604,66 @@ void LLVoiceChannelGroup::setState(EState state)
}
}
+void LLVoiceChannelGroup::voiceCallCapCoro(std::string url)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("voiceCallCapCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLSD postData;
+ postData["method"] = "call";
+ postData["session-id"] = mSessionID;
+
+ LL_INFOS("Voice", "voiceCallCapCoro") << "Generic POST for " << url << LL_ENDL;
+
+ LLSD result = httpAdapter->postAndYield(httpRequest, url, postData);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(mSessionID);
+ if (!channelp)
+ {
+ LL_WARNS("Voice") << "Unable to retrieve channel with Id = " << mSessionID << LL_ENDL;
+ return;
+ }
+
+ if (!status)
+ {
+ if (status == LLCore::HttpStatus(HTTP_FORBIDDEN))
+ {
+ //403 == no ability
+ LLNotificationsUtil::add(
+ "VoiceNotAllowed",
+ channelp->getNotifyArgs());
+ }
+ else
+ {
+ LLNotificationsUtil::add(
+ "VoiceCallGenericError",
+ channelp->getNotifyArgs());
+ }
+ channelp->deactivate();
+ return;
+ }
+
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+
+ LLSD::map_const_iterator iter;
+ for (iter = result.beginMap(); iter != result.endMap(); ++iter)
+ {
+ LL_DEBUGS("Voice") << "LLVoiceCallCapResponder::result got "
+ << iter->first << LL_ENDL;
+ }
+
+ channelp->setChannelInfo(
+ result["voice_credentials"]["channel_uri"].asString(),
+ result["voice_credentials"]["channel_credentials"].asString());
+
+}
+
+
//
// LLVoiceChannelProximal
//
diff --git a/indra/newview/llvoicechannel.h b/indra/newview/llvoicechannel.h
index fed44974fd..ef15b2c79e 100755
--- a/indra/newview/llvoicechannel.h
+++ b/indra/newview/llvoicechannel.h
@@ -29,6 +29,8 @@
#include "llhandle.h"
#include "llvoiceclient.h"
+#include "lleventcoro.h"
+#include "llcoros.h"
class LLPanel;
@@ -157,6 +159,8 @@ protected:
virtual void setState(EState state);
private:
+ void voiceCallCapCoro(std::string url);
+
U32 mRetries;
BOOL mIsRetrying;
};
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index a6a7a35b03..f50ffdeae7 100755
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -64,6 +64,8 @@
#include "llviewernetwork.h"
#include "llnotificationsutil.h"
+#include "llcorehttputil.h"
+
#include "stringize.h"
// for base64 decoding
@@ -122,66 +124,6 @@ static int scale_speaker_volume(float volume)
}
-class LLVivoxVoiceAccountProvisionResponder :
- public LLHTTPClient::Responder
-{
- LOG_CLASS(LLVivoxVoiceAccountProvisionResponder);
-public:
- LLVivoxVoiceAccountProvisionResponder(int retries)
- {
- mRetries = retries;
- }
-
-private:
- /* virtual */ void httpFailure()
- {
- LL_WARNS("Voice") << "ProvisionVoiceAccountRequest returned an error, "
- << ( (mRetries > 0) ? "retrying" : "too many retries (giving up)" )
- << " " << dumpResponse() << LL_ENDL;
-
- if ( mRetries > 0 )
- {
- LLVivoxVoiceClient::getInstance()->requestVoiceAccountProvision(mRetries - 1);
- }
- else
- {
- LLVivoxVoiceClient::getInstance()->giveUp();
- }
- }
-
- /* virtual */ void httpSuccess()
- {
- std::string voice_sip_uri_hostname;
- std::string voice_account_server_uri;
-
- 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();
-
- // this key is actually misnamed -- it will be an entire URI, not just a hostname.
- if(content.has("voice_account_server_name"))
- voice_account_server_uri = content["voice_account_server_name"].asString();
-
- LLVivoxVoiceClient::getInstance()->login(
- content["username"].asString(),
- content["password"].asString(),
- voice_sip_uri_hostname,
- voice_account_server_uri);
- }
-
-private:
- int mRetries;
-};
-
-
-
///////////////////////////////////////////////////////////////////////////////////////////////
class LLVivoxVoiceClientMuteListObserver : public LLMuteListObserver
@@ -194,59 +136,6 @@ static LLVivoxVoiceClientMuteListObserver mutelist_listener;
static bool sMuteListListener_listening = false;
///////////////////////////////////////////////////////////////////////////////////////////////
-
-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 httpFailure();
- /* virtual */ void httpSuccess();
-
- LLVivoxVoiceClient::state mRequestingState; // state
-};
-
-void LLVivoxVoiceClientCapResponder::httpFailure()
-{
- LL_WARNS("Voice") << dumpResponse() << LL_ENDL;
- LLVivoxVoiceClient::getInstance()->sessionTerminate();
-}
-
-void LLVivoxVoiceClientCapResponder::httpSuccess()
-{
- LLSD::map_const_iterator iter;
-
- 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"];
- if ( voice_credentials.has("channel_uri") )
- {
- uri = voice_credentials["channel_uri"].asString();
- }
- if ( voice_credentials.has("channel_credentials") )
- {
- credentials =
- voice_credentials["channel_credentials"].asString();
- }
- }
-
- // set the spatial channel. If no voice credentials or uri are
- // available, then we simply drop out of voice spatially.
- if(LLVivoxVoiceClient::getInstance()->parcelVoiceInfoReceived(mRequestingState))
- {
- LLVivoxVoiceClient::getInstance()->setSpatialChannel(uri, credentials);
- }
-}
-
static LLProcessPtr sGatewayPtr;
static bool isGatewayRunning()
@@ -556,16 +445,51 @@ void LLVivoxVoiceClient::requestVoiceAccountProvision(S32 retries)
if ( !url.empty() )
{
- LLHTTPClient::post(
- url,
- LLSD(),
- new LLVivoxVoiceAccountProvisionResponder(retries));
-
+ LLCoros::instance().launch("LLVivoxVoiceClient::voiceAccountProvisionCoro",
+ boost::bind(&LLVivoxVoiceClient::voiceAccountProvisionCoro, this, url, retries));
setState(stateConnectorStart);
}
}
}
+void LLVivoxVoiceClient::voiceAccountProvisionCoro(std::string url, S32 retries)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("voiceAccountProvision", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
+
+ httpOpts->setRetries(retries);
+
+ LLSD result = httpAdapter->postAndYield(httpRequest, url, LLSD(), httpOpts);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS("Voice") << "Unable to provision voice account." << LL_ENDL;
+ giveUp();
+ return;
+ }
+
+ std::string voice_sip_uri_hostname;
+ std::string voice_account_server_uri;
+
+ //LL_DEBUGS("Voice") << "ProvisionVoiceAccountRequest response:" << dumpResponse() << LL_ENDL;
+
+ if (result.has("voice_sip_uri_hostname"))
+ voice_sip_uri_hostname = result["voice_sip_uri_hostname"].asString();
+
+ // this key is actually misnamed -- it will be an entire URI, not just a hostname.
+ if (result.has("voice_account_server_name"))
+ voice_account_server_uri = result["voice_account_server_name"].asString();
+
+ login(result["username"].asString(), result["password"].asString(),
+ voice_sip_uri_hostname, voice_account_server_uri);
+}
+
void LLVivoxVoiceClient::login(
const std::string& account_name,
const std::string& password,
@@ -4003,14 +3927,60 @@ bool LLVivoxVoiceClient::requestParcelVoiceInfo()
LLSD data;
LL_DEBUGS("Voice") << "sending ParcelVoiceInfoRequest (" << mCurrentRegionName << ", " << mCurrentParcelLocalID << ")" << LL_ENDL;
- LLHTTPClient::post(
- url,
- data,
- new LLVivoxVoiceClientCapResponder(getState()));
+ LLCoros::instance().launch("LLVivoxVoiceClient::parcelVoiceInfoRequestCoro",
+ boost::bind(&LLVivoxVoiceClient::parcelVoiceInfoRequestCoro, this, url));
return true;
}
}
+void LLVivoxVoiceClient::parcelVoiceInfoRequestCoro(std::string url)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("parcelVoiceInfoRequest", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ state requestingState = getState();
+
+ LLSD result = httpAdapter->postAndYield(httpRequest, url, LLSD());
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS("Voice") << "No voice on parcel" << LL_ENDL;
+ sessionTerminate();
+ return;
+ }
+
+ std::string uri;
+ std::string credentials;
+
+ if (result.has("voice_credentials"))
+ {
+ LLSD voice_credentials = result["voice_credentials"];
+ if (voice_credentials.has("channel_uri"))
+ {
+ uri = voice_credentials["channel_uri"].asString();
+ }
+ if (voice_credentials.has("channel_credentials"))
+ {
+ credentials =
+ voice_credentials["channel_credentials"].asString();
+ }
+ }
+
+ LL_INFOS("Voice") << "Voice URI is " << uri << LL_ENDL;
+
+ // set the spatial channel. If no voice credentials or uri are
+ // available, then we simply drop out of voice spatially.
+ if (parcelVoiceInfoReceived(requestingState))
+ {
+ setSpatialChannel(uri, credentials);
+ }
+
+}
+
void LLVivoxVoiceClient::switchChannel(
std::string uri,
bool spatial,
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index a4ec9f2a69..b12ed80e41 100755
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -37,6 +37,9 @@ class LLVivoxProtocolParser;
#include "llframetimer.h"
#include "llviewerregion.h"
#include "llcallingcard.h" // for LLFriendObserver
+#include "lleventcoro.h"
+#include "llcoros.h"
+#include <queue>
#ifdef LL_USESYSTEMLIBS
# include "expat.h"
@@ -46,7 +49,6 @@ class LLVivoxProtocolParser;
#include "llvoiceclient.h"
class LLAvatarName;
-class LLVivoxVoiceAccountProvisionResponder;
class LLVivoxVoiceClientMuteListObserver;
@@ -251,7 +253,6 @@ protected:
//////////////////////
// Vivox Specific definitions
- friend class LLVivoxVoiceAccountProvisionResponder;
friend class LLVivoxVoiceClientMuteListObserver;
friend class LLVivoxVoiceClientFriendsObserver;
@@ -635,6 +636,10 @@ protected:
void accountGetTemplateFontsResponse(int statusCode, const std::string &statusString);
private:
+
+ void voiceAccountProvisionCoro(std::string url, S32 retries);
+ void parcelVoiceInfoRequestCoro(std::string url);
+
LLVoiceVersionInfo mVoiceVersion;
/// Clean up objects created during a voice session.
diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp
index ddb7f7bfce..2033a5f36a 100755
--- a/indra/newview/llwebprofile.cpp
+++ b/indra/newview/llwebprofile.cpp
@@ -30,14 +30,17 @@
// libs
#include "llbufferstream.h"
-#include "llhttpclient.h"
#include "llimagepng.h"
#include "llplugincookiestore.h"
+#include "llsdserialize.h"
+
// newview
#include "llpanelprofile.h" // for getProfileURL(). FIXME: move the method to LLAvatarActions
#include "llviewermedia.h" // FIXME: don't use LLViewerMedia internals
+#include "llcorehttputil.h"
+
// third-party
#include "reader.h" // JSON
@@ -55,139 +58,6 @@
*/
///////////////////////////////////////////////////////////////////////////////
-// LLWebProfileResponders::ConfigResponder
-
-class LLWebProfileResponders::ConfigResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(LLWebProfileResponders::ConfigResponder);
-
-public:
- ConfigResponder(LLPointer<LLImageFormatted> imagep)
- : mImagep(imagep)
- {
- }
-
- // *TODO: Check for 'application/json' content type, and parse json at the base class.
- /*virtual*/ void completedRaw(
- const LLChannelDescriptors& channels,
- const LLIOPipe::buffer_ptr_t& buffer)
- {
- LLBufferStream istr(channels, buffer.get());
- std::stringstream strstrm;
- strstrm << istr.rdbuf();
- const std::string body = strstrm.str();
-
- if (getStatus() != HTTP_OK)
- {
- LL_WARNS() << "Failed to get upload config " << dumpResponse() << LL_ENDL;
- LLWebProfile::reportImageUploadStatus(false);
- return;
- }
-
- Json::Value root;
- Json::Reader reader;
- if (!reader.parse(body, root))
- {
- LL_WARNS() << "Failed to parse upload config: " << reader.getFormatedErrorMessages() << LL_ENDL;
- LLWebProfile::reportImageUploadStatus(false);
- return;
- }
-
- // *TODO: 404 = not supported by the grid
- // *TODO: increase timeout or handle 499 Expired
-
- // Convert config to LLSD.
- const Json::Value data = root["data"];
- const std::string upload_url = root["url"].asString();
- LLSD config;
- config["acl"] = data["acl"].asString();
- config["AWSAccessKeyId"] = data["AWSAccessKeyId"].asString();
- config["Content-Type"] = data["Content-Type"].asString();
- config["key"] = data["key"].asString();
- config["policy"] = data["policy"].asString();
- config["success_action_redirect"] = data["success_action_redirect"].asString();
- config["signature"] = data["signature"].asString();
- config["add_loc"] = data.get("add_loc", "0").asString();
- config["caption"] = data.get("caption", "").asString();
-
- // Do the actual image upload using the configuration.
- LL_DEBUGS("Snapshots") << "Got upload config, POSTing image to " << upload_url << ", config=[" << config << "]" << LL_ENDL;
- LLWebProfile::post(mImagep, config, upload_url);
- }
-
-private:
- LLPointer<LLImageFormatted> mImagep;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// LLWebProfilePostImageRedirectResponder
-class LLWebProfileResponders::PostImageRedirectResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(LLWebProfileResponders::PostImageRedirectResponder);
-
-public:
- /*virtual*/ void completedRaw(
- const LLChannelDescriptors& channels,
- const LLIOPipe::buffer_ptr_t& buffer)
- {
- if (getStatus() != HTTP_OK)
- {
- LL_WARNS() << "Failed to upload image " << dumpResponse() << LL_ENDL;
- LLWebProfile::reportImageUploadStatus(false);
- return;
- }
-
- LLBufferStream istr(channels, buffer.get());
- std::stringstream strstrm;
- strstrm << istr.rdbuf();
- const std::string body = strstrm.str();
- LL_INFOS() << "Image uploaded." << LL_ENDL;
- LL_DEBUGS("Snapshots") << "Uploading image succeeded. Response: [" << body << "]" << LL_ENDL;
- LLWebProfile::reportImageUploadStatus(true);
- }
-};
-
-
-///////////////////////////////////////////////////////////////////////////////
-// LLWebProfileResponders::PostImageResponder
-class LLWebProfileResponders::PostImageResponder : public LLHTTPClient::Responder
-{
- LOG_CLASS(LLWebProfileResponders::PostImageResponder);
-
-public:
- /*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 (getStatus() == HTTP_SEE_OTHER)
- {
- LLSD headers = LLViewerMedia::getHeaders();
- headers[HTTP_OUT_HEADER_COOKIE] = LLWebProfile::getAuthCookie();
- const std::string& redir_url = getResponseHeader(HTTP_IN_HEADER_LOCATION);
- if (redir_url.empty())
- {
- LL_WARNS() << "Received empty redirection URL " << dumpResponse() << LL_ENDL;
- LL_DEBUGS("Snapshots") << "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
- LLWebProfile::reportImageUploadStatus(false);
- }
- else
- {
- LL_DEBUGS("Snapshots") << "Got redirection URL: " << redir_url << LL_ENDL;
- LLHTTPClient::get(redir_url, new LLWebProfileResponders::PostImageRedirectResponder, headers);
- }
- }
- else
- {
- LL_WARNS() << "Unexpected POST response " << dumpResponse() << LL_ENDL;
- LL_DEBUGS("Snapshots") << "[headers:" << getResponseHeaders() << "]" << LL_ENDL;
- LLWebProfile::reportImageUploadStatus(false);
- }
- }
-};
-
-///////////////////////////////////////////////////////////////////////////////
// LLWebProfile
std::string LLWebProfile::sAuthCookie;
@@ -196,15 +66,9 @@ LLWebProfile::status_callback_t LLWebProfile::mStatusCallback;
// static
void LLWebProfile::uploadImage(LLPointer<LLImageFormatted> image, const std::string& caption, bool add_location)
{
- // Get upload configuration data.
- std::string config_url(getProfileURL(LLStringUtil::null) + "snapshots/s3_upload_config");
- config_url += "?caption=" + LLURI::escape(caption);
- config_url += "&add_loc=" + std::string(add_location ? "1" : "0");
-
- LL_DEBUGS("Snapshots") << "Requesting " << config_url << LL_ENDL;
- LLSD headers = LLViewerMedia::getHeaders();
- headers[HTTP_OUT_HEADER_COOKIE] = getAuthCookie();
- LLHTTPClient::get(config_url, new LLWebProfileResponders::ConfigResponder(image), headers);
+ LLCoros::instance().launch("LLWebProfile::uploadImageCoro",
+ boost::bind(&LLWebProfile::uploadImageCoro, image, caption, add_location));
+
}
// static
@@ -214,74 +78,178 @@ void LLWebProfile::setAuthCookie(const std::string& cookie)
sAuthCookie = cookie;
}
-// static
-void LLWebProfile::post(LLPointer<LLImageFormatted> image, const LLSD& config, const std::string& url)
+
+/*static*/
+LLCore::HttpHeaders::ptr_t LLWebProfile::buildDefaultHeaders()
{
- if (dynamic_cast<LLImagePNG*>(image.get()) == 0)
- {
- LL_WARNS() << "Image to upload is not a PNG" << LL_ENDL;
- llassert(dynamic_cast<LLImagePNG*>(image.get()) != 0);
- return;
- }
+ LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
+ LLSD headers = LLViewerMedia::getHeaders();
- const std::string boundary = "----------------------------0123abcdefab";
+ for (LLSD::map_iterator it = headers.beginMap(); it != headers.endMap(); ++it)
+ {
+ httpHeaders->append((*it).first, (*it).second.asStringRef());
+ }
- LLSD headers = LLViewerMedia::getHeaders();
- headers[HTTP_OUT_HEADER_COOKIE] = getAuthCookie();
- headers[HTTP_OUT_HEADER_CONTENT_TYPE] = "multipart/form-data; boundary=" + boundary;
+ return httpHeaders;
+}
- std::ostringstream body;
- // *NOTE: The order seems to matter.
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"key\"\r\n\r\n"
- << config["key"].asString() << "\r\n";
+/*static*/
+void LLWebProfile::uploadImageCoro(LLPointer<LLImageFormatted> image, std::string caption, bool addLocation)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("genericPostCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"AWSAccessKeyId\"\r\n\r\n"
- << config["AWSAccessKeyId"].asString() << "\r\n";
+ if (dynamic_cast<LLImagePNG*>(image.get()) == 0)
+ {
+ LL_WARNS() << "Image to upload is not a PNG" << LL_ENDL;
+ llassert(dynamic_cast<LLImagePNG*>(image.get()) != 0);
+ return;
+ }
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"acl\"\r\n\r\n"
- << config["acl"].asString() << "\r\n";
+ httpOpts->setWantHeaders(true);
+ httpOpts->setFollowRedirects(false);
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"Content-Type\"\r\n\r\n"
- << config["Content-Type"].asString() << "\r\n";
+ // Get upload configuration data.
+ std::string configUrl(getProfileURL(std::string()) + "snapshots/s3_upload_config");
+ configUrl += "?caption=" + LLURI::escape(caption);
+ configUrl += "&add_loc=" + std::string(addLocation ? "1" : "0");
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"policy\"\r\n\r\n"
- << config["policy"].asString() << "\r\n";
+ LL_DEBUGS("Snapshots") << "Requesting " << configUrl << LL_ENDL;
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"signature\"\r\n\r\n"
- << config["signature"].asString() << "\r\n";
+ httpHeaders = buildDefaultHeaders();
+ httpHeaders->append(HTTP_OUT_HEADER_COOKIE, getAuthCookie());
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"success_action_redirect\"\r\n\r\n"
- << config["success_action_redirect"].asString() << "\r\n";
+ LLSD result = httpAdapter->getJsonAndYield(httpRequest, configUrl, httpOpts, httpHeaders);
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"file\"; filename=\"snapshot.png\"\r\n"
- << "Content-Type: image/png\r\n\r\n";
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
- // Insert the image data.
- // *FIX: Treating this as a string will probably screw it up ...
- U8* image_data = image->getData();
- for (S32 i = 0; i < image->getDataSize(); ++i)
- {
- body << image_data[i];
- }
+ if (!status)
+ {
+ LL_WARNS("Snapshots") << "Failed to get image upload config" << LL_ENDL;
+ LLWebProfile::reportImageUploadStatus(false);
+ return;
+ }
+
+ // Ready to build our image post body.
+
+ const LLSD &data = result["data"];
+ const std::string &uploadUrl = result["url"].asStringRef();
+ const std::string boundary = "----------------------------0123abcdefab";
+
+ // a new set of headers.
+ httpHeaders = LLWebProfile::buildDefaultHeaders();
+ httpHeaders->append(HTTP_OUT_HEADER_COOKIE, getAuthCookie());
+ httpHeaders->remove(HTTP_OUT_HEADER_CONTENT_TYPE);
+ httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "multipart/form-data; boundary=" + boundary);
+
+ LLCore::BufferArray::ptr_t body = LLWebProfile::buildPostData(data, image, boundary);
+
+ result = httpAdapter->postAndYield(httpRequest, uploadUrl, body, httpOpts, httpHeaders);
+
+ body.reset();
+ httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
- body << "\r\n--" << boundary << "--\r\n";
+ if (!status && (status != LLCore::HttpStatus(HTTP_SEE_OTHER)))
+ {
+ LL_WARNS("Snapshots") << "Failed to upload image data." << LL_ENDL;
+ LLWebProfile::reportImageUploadStatus(false);
+ return;
+ }
- // postRaw() takes ownership of the buffer and releases it later.
- size_t size = body.str().size();
- U8 *data = new U8[size];
- memcpy(data, body.str().data(), size);
+ LLSD resultHeaders = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
- // Send request, successful upload will trigger posting metadata.
- LLHTTPClient::postRaw(url, data, size, new LLWebProfileResponders::PostImageResponder(), headers);
+ httpHeaders = LLWebProfile::buildDefaultHeaders();
+ httpHeaders->append(HTTP_OUT_HEADER_COOKIE, getAuthCookie());
+
+ const std::string& redirUrl = resultHeaders[HTTP_IN_HEADER_LOCATION].asStringRef();
+
+ if (redirUrl.empty())
+ {
+ LL_WARNS("Snapshots") << "Received empty redirection URL in post image." << LL_ENDL;
+ LLWebProfile::reportImageUploadStatus(false);
+ }
+
+ LL_DEBUGS("Snapshots") << "Got redirection URL: " << redirUrl << LL_ENDL;
+
+ result = httpAdapter->getRawAndYield(httpRequest, redirUrl, httpOpts, httpHeaders);
+
+ httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (status != LLCore::HttpStatus(HTTP_OK))
+ {
+ LL_WARNS("Snapshots") << "Failed to upload image." << LL_ENDL;
+ LLWebProfile::reportImageUploadStatus(false);
+ return;
+ }
+
+ //LLSD raw = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_RAW];
+
+ LL_INFOS("Snapshots") << "Image uploaded." << LL_ENDL;
+ //LL_DEBUGS("Snapshots") << "Uploading image succeeded. Response: [" << raw.asString() << "]" << LL_ENDL;
+ LLWebProfile::reportImageUploadStatus(true);
+
+
+}
+
+/*static*/
+LLCore::BufferArray::ptr_t LLWebProfile::buildPostData(const LLSD &data, LLPointer<LLImageFormatted> &image, const std::string &boundary)
+{
+ LLCore::BufferArray::ptr_t body(new LLCore::BufferArray);
+ LLCore::BufferArrayStream bas(body.get());
+
+ // *NOTE: The order seems to matter.
+ bas << "--" << boundary << "\r\n"
+ << "Content-Disposition: form-data; name=\"key\"\r\n\r\n"
+ << data["key"].asString() << "\r\n";
+
+ bas << "--" << boundary << "\r\n"
+ << "Content-Disposition: form-data; name=\"AWSAccessKeyId\"\r\n\r\n"
+ << data["AWSAccessKeyId"].asString() << "\r\n";
+
+ bas << "--" << boundary << "\r\n"
+ << "Content-Disposition: form-data; name=\"acl\"\r\n\r\n"
+ << data["acl"].asString() << "\r\n";
+
+ bas << "--" << boundary << "\r\n"
+ << "Content-Disposition: form-data; name=\"Content-Type\"\r\n\r\n"
+ << data["Content-Type"].asString() << "\r\n";
+
+ bas << "--" << boundary << "\r\n"
+ << "Content-Disposition: form-data; name=\"policy\"\r\n\r\n"
+ << data["policy"].asString() << "\r\n";
+
+ bas << "--" << boundary << "\r\n"
+ << "Content-Disposition: form-data; name=\"signature\"\r\n\r\n"
+ << data["signature"].asString() << "\r\n";
+
+ bas << "--" << boundary << "\r\n"
+ << "Content-Disposition: form-data; name=\"success_action_redirect\"\r\n\r\n"
+ << data["success_action_redirect"].asString() << "\r\n";
+
+ bas << "--" << boundary << "\r\n"
+ << "Content-Disposition: form-data; name=\"file\"; filename=\"snapshot.png\"\r\n"
+ << "Content-Type: image/png\r\n\r\n";
+
+ // Insert the image data.
+ //char *datap = (char *)(image->getData());
+ //bas.write(datap, image->getDataSize());
+ U8* image_data = image->getData();
+ for (S32 i = 0; i < image->getDataSize(); ++i)
+ {
+ bas << image_data[i];
+ }
+
+ bas << "\r\n--" << boundary << "--\r\n";
+
+ return body;
}
// static
diff --git a/indra/newview/llwebprofile.h b/indra/newview/llwebprofile.h
index 10279bffac..6227e00afe 100755
--- a/indra/newview/llwebprofile.h
+++ b/indra/newview/llwebprofile.h
@@ -28,6 +28,10 @@
#define LL_LLWEBPROFILE_H
#include "llimage.h"
+#include "lleventcoro.h"
+#include "llcoros.h"
+#include "httpheaders.h"
+#include "bufferarray.h"
namespace LLWebProfileResponders
{
@@ -54,11 +58,11 @@ public:
static void setImageUploadResultCallback(status_callback_t cb) { mStatusCallback = cb; }
private:
- friend class LLWebProfileResponders::ConfigResponder;
- friend class LLWebProfileResponders::PostImageResponder;
- friend class LLWebProfileResponders::PostImageRedirectResponder;
+ static LLCore::HttpHeaders::ptr_t buildDefaultHeaders();
+
+ static void uploadImageCoro(LLPointer<LLImageFormatted> image, std::string caption, bool add_location);
+ static LLCore::BufferArray::ptr_t buildPostData(const LLSD &data, LLPointer<LLImageFormatted> &image, const std::string &boundary);
- static void post(LLPointer<LLImageFormatted> image, const LLSD& config, const std::string& url);
static void reportImageUploadStatus(bool ok);
static std::string getAuthCookie();
diff --git a/indra/newview/llwlhandlers.cpp b/indra/newview/llwlhandlers.cpp
index 3bedfbe502..ff15afa598 100755
--- a/indra/newview/llwlhandlers.cpp
+++ b/indra/newview/llwlhandlers.cpp
@@ -32,6 +32,7 @@
#include "llviewerregion.h"
#include "llenvmanager.h"
#include "llnotificationsutil.h"
+#include "llcorehttputil.h"
/****
* LLEnvironmentRequest
@@ -81,55 +82,62 @@ bool LLEnvironmentRequest::doRequest()
return false;
}
- LL_INFOS("WindlightCaps") << "Requesting region windlight settings via " << url << LL_ENDL;
- LLHTTPClient::get(url, new LLEnvironmentRequestResponder());
- return true;
-}
-
-/****
- * LLEnvironmentRequestResponder
- ****/
-int LLEnvironmentRequestResponder::sCount = 0; // init to 0
+ std::string coroname =
+ LLCoros::instance().launch("LLEnvironmentRequest::environmentRequestCoro",
+ boost::bind(&LLEnvironmentRequest::environmentRequestCoro, url));
-LLEnvironmentRequestResponder::LLEnvironmentRequestResponder()
-{
- mID = ++sCount;
+ LL_INFOS("WindlightCaps") << "Requesting region windlight settings via " << url << LL_ENDL;
+ return true;
}
-/*virtual*/ void LLEnvironmentRequestResponder::httpSuccess()
-{
- const LLSD& unvalidated_content = getContent();
- LL_INFOS("WindlightCaps") << "Received region windlight settings" << LL_ENDL;
- if (mID != sCount)
- {
- LL_INFOS("WindlightCaps") << "Got superseded by another responder; ignoring..." << LL_ENDL;
- return;
- }
-
- LLUUID regionId;
- if( gAgent.getRegion() )
- {
- regionId = gAgent.getRegion()->getRegionID();
- }
-
- if (unvalidated_content[0]["regionID"].asUUID() != regionId )
- {
- LL_WARNS("WindlightCaps") << "Not in the region from where this data was received (wanting "
- << regionId << " but got " << unvalidated_content[0]["regionID"].asUUID()
- << ") - ignoring..." << LL_ENDL;
- return;
- }
+S32 LLEnvironmentRequest::sLastRequest = 0;
- LLEnvManagerNew::getInstance()->onRegionSettingsResponse(unvalidated_content);
-}
-/*virtual*/
-void LLEnvironmentRequestResponder::httpFailure()
+//static
+void LLEnvironmentRequest::environmentRequestCoro(std::string url)
{
- LL_WARNS("WindlightCaps") << "Got an error, not using region windlight... "
- << dumpResponse() << LL_ENDL;
- LLEnvManagerNew::getInstance()->onRegionSettingsResponse(LLSD());
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ S32 requestId = ++LLEnvironmentRequest::sLastRequest;
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("EnvironmentRequest", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLSD result = httpAdapter->getAndYield(httpRequest, url);
+
+ if (requestId != LLEnvironmentRequest::sLastRequest)
+ {
+ LL_INFOS("WindlightCaps") << "Got superseded by another responder; ignoring..." << LL_ENDL;
+ return;
+ }
+
+ LLSD httpResults = result["http_result"];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+ if (!status)
+ {
+ LL_WARNS("WindlightCaps") << "Got an error, not using region windlight... " << LL_ENDL;
+ LLEnvManagerNew::getInstance()->onRegionSettingsResponse(LLSD());
+ return;
+ }
+ result = result["content"];
+ LL_INFOS("WindlightCaps") << "Received region windlight settings" << LL_ENDL;
+
+ LLUUID regionId;
+ if (gAgent.getRegion())
+ {
+ regionId = gAgent.getRegion()->getRegionID();
+ }
+
+ if (result[0]["regionID"].asUUID() != regionId)
+ {
+ LL_WARNS("WindlightCaps") << "Not in the region from where this data was received (wanting "
+ << regionId << " but got " << result[0]["regionID"].asUUID()
+ << ") - ignoring..." << LL_ENDL;
+ return;
+ }
+
+ LLEnvManagerNew::getInstance()->onRegionSettingsResponse(result);
}
+
/****
* LLEnvironmentApply
****/
@@ -161,53 +169,86 @@ bool LLEnvironmentApply::initiateRequest(const LLSD& content)
return false;
}
- LL_INFOS("WindlightCaps") << "Sending windlight settings to " << url << LL_ENDL;
- LL_DEBUGS("WindlightCaps") << "content: " << content << LL_ENDL;
- LLHTTPClient::post(url, content, new LLEnvironmentApplyResponder());
+ LL_INFOS("WindlightCaps") << "Sending windlight settings to " << url << LL_ENDL;
+ LL_DEBUGS("WindlightCaps") << "content: " << content << LL_ENDL;
+
+ std::string coroname =
+ LLCoros::instance().launch("LLEnvironmentApply::environmentApplyCoro",
+ boost::bind(&LLEnvironmentApply::environmentApplyCoro, url, content));
return true;
}
-/****
- * LLEnvironmentApplyResponder
- ****/
-/*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 "
- << gAgent.getRegion()->getRegionID() << ", reply is from " << content["regionID"].asUUID()
- << "); ignoring..." << LL_ENDL;
- return;
- }
- else if (content["success"].asBoolean())
- {
- LL_DEBUGS("WindlightCaps") << "Success in applying windlight settings to region " << content["regionID"].asUUID() << LL_ENDL;
- LLEnvManagerNew::instance().onRegionSettingsApplyResponse(true);
- }
- else
- {
- 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);
- LLEnvManagerNew::instance().onRegionSettingsApplyResponse(false);
- }
-}
-/*virtual*/
-void LLEnvironmentApplyResponder::httpFailure()
+void LLEnvironmentApply::environmentApplyCoro(std::string url, LLSD content)
{
- LL_WARNS("WindlightCaps") << "Couldn't apply windlight settings to region! "
- << dumpResponse() << LL_ENDL;
-
- LLSD args(LLSD::emptyMap());
- std::stringstream msg;
- msg << getReason() << " (Code " << getStatus() << ")";
- args["FAIL_REASON"] = msg.str();
- LLNotificationsUtil::add("WLRegionApplyFail", args);
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("EnvironmentApply", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+ LLSD result = httpAdapter->postAndYield(httpRequest, url, content);
+
+ LLSD notify; // for error reporting. If there is something to report to user this will be defined.
+ /*
+ * Expecting reply from sim in form of:
+ * {
+ * regionID : uuid,
+ * messageID: uuid,
+ * success : true
+ * }
+ * or
+ * {
+ * regionID : uuid,
+ * success : false,
+ * fail_reason : string
+ * }
+ */
+
+ do // while false.
+ { // Breaks from loop in the case of an error.
+
+ LLSD httpResults = result["http_result"];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+ if (!status)
+ {
+ LL_WARNS("WindlightCaps") << "Couldn't apply windlight settings to region! " << LL_ENDL;
+
+ std::stringstream msg;
+ msg << status.toString() << " (Code " << status.toTerseString() << ")";
+ notify = LLSD::emptyMap();
+ notify["FAIL_REASON"] = msg.str();
+ break;
+ }
+
+ if (!result.has("regionID"))
+ {
+ notify = LLSD::emptyMap();
+ notify["FAIL_REASON"] = "Missing regionID, malformed response";
+ break;
+ }
+ else if (result["regionID"].asUUID() != gAgent.getRegion()->getRegionID())
+ {
+ // note that there is no report to the user in this failure case.
+ LL_WARNS("WindlightCaps") << "No longer in the region where data was sent (currently "
+ << gAgent.getRegion()->getRegionID() << ", reply is from " << result["regionID"].asUUID()
+ << "); ignoring..." << LL_ENDL;
+ break;
+ }
+ else if (!result["success"].asBoolean())
+ {
+ LL_WARNS("WindlightCaps") << "Region couldn't apply windlight settings! " << LL_ENDL;
+ notify = LLSD::emptyMap();
+ notify["FAIL_REASON"] = result["fail_reason"].asString();
+ break;
+ }
+
+ LL_DEBUGS("WindlightCaps") << "Success in applying windlight settings to region " << result["regionID"].asUUID() << LL_ENDL;
+ LLEnvManagerNew::instance().onRegionSettingsApplyResponse(true);
+
+ } while (false);
+
+ if (!notify.isUndefined())
+ {
+ LLNotificationsUtil::add("WLRegionApplyFail", notify);
+ LLEnvManagerNew::instance().onRegionSettingsApplyResponse(false);
+ }
}
diff --git a/indra/newview/llwlhandlers.h b/indra/newview/llwlhandlers.h
index 089c799da7..eb2bbf9553 100755
--- a/indra/newview/llwlhandlers.h
+++ b/indra/newview/llwlhandlers.h
@@ -28,7 +28,7 @@
#define LL_LLWLHANDLERS_H
#include "llviewerprecompiledheaders.h"
-#include "llhttpclient.h"
+#include "llcoros.h"
class LLEnvironmentRequest
{
@@ -40,21 +40,10 @@ public:
private:
static void onRegionCapsReceived(const LLUUID& region_id);
static bool doRequest();
-};
-
-class LLEnvironmentRequestResponder: public LLHTTPClient::Responder
-{
- LOG_CLASS(LLEnvironmentRequestResponder);
-private:
- /* virtual */ void httpSuccess();
- /* virtual */ void httpFailure();
-private:
- friend class LLEnvironmentRequest;
+ static void environmentRequestCoro(std::string url);
- LLEnvironmentRequestResponder();
- static int sCount;
- int mID;
+ static S32 sLastRequest;
};
class LLEnvironmentApply
@@ -67,35 +56,8 @@ public:
private:
static clock_t sLastUpdate;
static clock_t UPDATE_WAIT_SECONDS;
-};
-class LLEnvironmentApplyResponder: public LLHTTPClient::Responder
-{
- LOG_CLASS(LLEnvironmentApplyResponder);
-private:
- /*
- * Expecting reply from sim in form of:
- * {
- * regionID : uuid,
- * messageID: uuid,
- * success : true
- * }
- * or
- * {
- * regionID : uuid,
- * success : false,
- * fail_reason : string
- * }
- */
- /* virtual */ void httpSuccess();
-
- // non-2xx errors only
- /* virtual */ void httpFailure();
-
-private:
- friend class LLEnvironmentApply;
-
- LLEnvironmentApplyResponder() {}
+ static void environmentApplyCoro(std::string url, LLSD content);
};
#endif // LL_LLWLHANDLERS_H
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index c12c2cc24c..5828aee7fc 100755
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -35,6 +35,11 @@
#include "llxmlrpclistener.h"
#include "llcurl.h"
+#include "httpcommon.h"
+#include "httprequest.h"
+#include "httpoptions.h"
+#include "httpheaders.h"
+#include "bufferarray.h"
#include "llviewercontrol.h"
// Have to include these last to avoid queue redefinition!
@@ -43,6 +48,13 @@
#include "llappviewer.h"
#include "lltrans.h"
+#include "boost/move/unique_ptr.hpp"
+
+namespace boost
+{
+ using ::boost::movelib::unique_ptr; // move unique_ptr into the boost namespace.
+}
+
// Static instance of LLXMLRPCListener declared here so that every time we
// bring in this code, we instantiate a listener. If we put the static
// instance of LLXMLRPCListener into llxmlrpclistener.cpp, the linker would
@@ -155,55 +167,158 @@ XMLRPC_VALUE LLXMLRPCValue::getValue() const
}
+class LLXMLRPCTransaction::Handler : public LLCore::HttpHandler
+{
+public:
+ Handler(LLCore::HttpRequest::ptr_t &request, LLXMLRPCTransaction::Impl *impl);
+ virtual ~Handler();
+
+ virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response);
+
+ typedef boost::unique_ptr<LLXMLRPCTransaction::Handler> ptr_t;
+
+private:
+
+ LLXMLRPCTransaction::Impl *mImpl;
+ LLCore::HttpRequest::ptr_t mRequest;
+};
+
class LLXMLRPCTransaction::Impl
{
public:
typedef LLXMLRPCTransaction::EStatus EStatus;
- LLCurlEasyRequest* mCurlRequest;
+ LLCore::HttpRequest::ptr_t mHttpRequest;
+
+
+ EStatus mStatus;
+ CURLcode mCurlCode;
+ std::string mStatusMessage;
+ std::string mStatusURI;
+ LLCore::HttpResponse::TransferStats::ptr_t mTransferStats;
+ Handler::ptr_t mHandler;
+ LLCore::HttpHandle mPostH;
- EStatus mStatus;
- CURLcode mCurlCode;
- std::string mStatusMessage;
- std::string mStatusURI;
- LLCurl::TransferInfo mTransferInfo;
-
std::string mURI;
- char* mRequestText;
- int mRequestTextSize;
-
+
std::string mProxyAddress;
std::string mResponseText;
XMLRPC_REQUEST mResponse;
std::string mCertStore;
LLPointer<LLCertificate> mErrorCert;
-
+
Impl(const std::string& uri, XMLRPC_REQUEST request, bool useGzip);
Impl(const std::string& uri,
- const std::string& method, LLXMLRPCValue params, bool useGzip);
+ const std::string& method, LLXMLRPCValue params, bool useGzip);
~Impl();
-
+
bool process();
-
- void setStatus(EStatus code,
- const std::string& message = "", const std::string& uri = "");
- void setCurlStatus(CURLcode);
+
+ void setStatus(EStatus code, const std::string& message = "", const std::string& uri = "");
+ void setHttpStatus(const LLCore::HttpStatus &status);
private:
void init(XMLRPC_REQUEST request, bool useGzip);
- static int _sslCertVerifyCallback(X509_STORE_CTX *ctx, void *param);
- static CURLcode _sslCtxFunction(CURL * curl, void *sslctx, void *param);
- static size_t curlDownloadCallback(
- char* data, size_t size, size_t nmemb, void* user_data);
};
+LLXMLRPCTransaction::Handler::Handler(LLCore::HttpRequest::ptr_t &request,
+ LLXMLRPCTransaction::Impl *impl) :
+ mImpl(impl),
+ mRequest(request)
+{
+}
+
+LLXMLRPCTransaction::Handler::~Handler()
+{
+}
+
+void LLXMLRPCTransaction::Handler::onCompleted(LLCore::HttpHandle handle,
+ LLCore::HttpResponse * response)
+{
+ LLCore::HttpStatus status = response->getStatus();
+
+ if (!status)
+ {
+ if ((status.toULong() != CURLE_SSL_PEER_CERTIFICATE) &&
+ (status.toULong() != CURLE_SSL_CACERT))
+ {
+ // if we have a curl error that's not already been handled
+ // (a non cert error), then generate the error message as
+ // appropriate
+ mImpl->setHttpStatus(status);
+ LLCertificate *errordata = static_cast<LLCertificate *>(status.getErrorData());
+
+ if (errordata)
+ {
+ mImpl->mErrorCert = LLPointer<LLCertificate>(errordata);
+ status.setErrorData(NULL);
+ errordata->unref();
+ }
+
+ LL_WARNS() << "LLXMLRPCTransaction error "
+ << status.toHex() << ": " << status.toString() << LL_ENDL;
+ LL_WARNS() << "LLXMLRPCTransaction request URI: "
+ << mImpl->mURI << LL_ENDL;
+ }
+
+ return;
+ }
+
+ mImpl->setStatus(LLXMLRPCTransaction::StatusComplete);
+ mImpl->mTransferStats = response->getTransferStats();
+
+ // the contents of a buffer array are potentially noncontiguous, so we
+ // will need to copy them into an contiguous block of memory for XMLRPC.
+ LLCore::BufferArray *body = response->getBody();
+ char * bodydata = new char[body->size()];
+
+ body->read(0, bodydata, body->size());
+
+ mImpl->mResponse = XMLRPC_REQUEST_FromXML(bodydata, body->size(), 0);
+
+ delete[] bodydata;
+
+ bool hasError = false;
+ bool hasFault = false;
+ int faultCode = 0;
+ std::string faultString;
+
+ LLXMLRPCValue error(XMLRPC_RequestGetError(mImpl->mResponse));
+ if (error.isValid())
+ {
+ hasError = true;
+ faultCode = error["faultCode"].asInt();
+ faultString = error["faultString"].asString();
+ }
+ else if (XMLRPC_ResponseIsFault(mImpl->mResponse))
+ {
+ hasFault = true;
+ faultCode = XMLRPC_GetResponseFaultCode(mImpl->mResponse);
+ faultString = XMLRPC_GetResponseFaultString(mImpl->mResponse);
+ }
+
+ if (hasError || hasFault)
+ {
+ mImpl->setStatus(LLXMLRPCTransaction::StatusXMLRPCError);
+
+ LL_WARNS() << "LLXMLRPCTransaction XMLRPC "
+ << (hasError ? "error " : "fault ")
+ << faultCode << ": "
+ << faultString << LL_ENDL;
+ LL_WARNS() << "LLXMLRPCTransaction request URI: "
+ << mImpl->mURI << LL_ENDL;
+ }
+
+}
+
+//=========================================================================
+
LLXMLRPCTransaction::Impl::Impl(const std::string& uri,
XMLRPC_REQUEST request, bool useGzip)
- : mCurlRequest(0),
+ : mHttpRequest(),
mStatus(LLXMLRPCTransaction::StatusNotStarted),
mURI(uri),
- mRequestText(0),
mResponse(0)
{
init(request, useGzip);
@@ -212,10 +327,9 @@ LLXMLRPCTransaction::Impl::Impl(const std::string& uri,
LLXMLRPCTransaction::Impl::Impl(const std::string& uri,
const std::string& method, LLXMLRPCValue params, bool useGzip)
- : mCurlRequest(0),
+ : mHttpRequest(),
mStatus(LLXMLRPCTransaction::StatusNotStarted),
mURI(uri),
- mRequestText(0),
mResponse(0)
{
XMLRPC_REQUEST request = XMLRPC_RequestNew();
@@ -231,127 +345,53 @@ LLXMLRPCTransaction::Impl::Impl(const std::string& uri,
XMLRPC_RequestFree(request, 1);
}
-// _sslCertVerifyCallback
-// callback called when a cert verification is requested.
-// calls SECAPI to validate the context
-int LLXMLRPCTransaction::Impl::_sslCertVerifyCallback(X509_STORE_CTX *ctx, void *param)
+void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip)
{
- LLXMLRPCTransaction::Impl *transaction = (LLXMLRPCTransaction::Impl *)param;
- LLPointer<LLCertificateStore> store = gSecAPIHandler->getCertificateStore(transaction->mCertStore);
- LLPointer<LLCertificateChain> chain = gSecAPIHandler->getCertificateChain(ctx);
- LLSD validation_params = LLSD::emptyMap();
- LLURI uri(transaction->mURI);
- validation_params[CERT_HOSTNAME] = uri.hostName();
- try
- {
- // don't validate hostname. Let libcurl do it instead. That way, it'll handle redirects
- store->validate(VALIDATION_POLICY_SSL & (~VALIDATION_POLICY_HOSTNAME), chain, validation_params);
- }
- catch (LLCertValidationTrustException& cert_exception)
- {
- // this exception is is handled differently than the general cert
- // exceptions, as we allow the user to actually add the certificate
- // for trust.
- // therefore we pass back a different error code
- // NOTE: We're currently 'wired' to pass around CURL error codes. This is
- // somewhat clumsy, as we may run into errors that do not map directly to curl
- // error codes. Should be refactored with login refactoring, perhaps.
- transaction->mCurlCode = CURLE_SSL_CACERT;
- // set the status directly. set curl status generates error messages and we want
- // to use the fixed ones from the exceptions
- transaction->setStatus(StatusCURLError, cert_exception.getMessage(), std::string());
- // We should probably have a more generic way of passing information
- // back to the error handlers.
- transaction->mErrorCert = cert_exception.getCert();
- return 0;
- }
- catch (LLCertException& cert_exception)
- {
- transaction->mCurlCode = CURLE_SSL_PEER_CERTIFICATE;
- // set the status directly. set curl status generates error messages and we want
- // to use the fixed ones from the exceptions
- transaction->setStatus(StatusCURLError, cert_exception.getMessage(), std::string());
- transaction->mErrorCert = cert_exception.getCert();
- return 0;
- }
- catch (...)
- {
- // any other odd error, we just handle as a connect error.
- transaction->mCurlCode = CURLE_SSL_CONNECT_ERROR;
- transaction->setCurlStatus(CURLE_SSL_CONNECT_ERROR);
- return 0;
- }
- return 1;
-}
+ LLCore::HttpOptions::ptr_t httpOpts;
+ LLCore::HttpHeaders::ptr_t httpHeaders;
-// _sslCtxFunction
-// Callback function called when an SSL Context is created via CURL
-// used to configure the context for custom cert validate(<, <#const & xs#>, <#T * #>, <#long #>)tion
-// based on SECAPI
-
-CURLcode LLXMLRPCTransaction::Impl::_sslCtxFunction(CURL * curl, void *sslctx, void *param)
-{
- SSL_CTX * ctx = (SSL_CTX *) sslctx;
- // disable any default verification for server certs
- SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
- // set the verification callback.
- SSL_CTX_set_cert_verify_callback(ctx, _sslCertVerifyCallback, param);
- // the calls are void
- return CURLE_OK;
-
-}
-void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip)
-{
- if (!mCurlRequest)
+ if (!mHttpRequest)
{
- mCurlRequest = new LLCurlEasyRequest();
+ mHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest);
}
- if(!mCurlRequest->isValid())
- {
- LL_WARNS() << "mCurlRequest is invalid." << LL_ENDL ;
- delete mCurlRequest ;
- mCurlRequest = NULL ;
- return ;
- }
+ // LLRefCounted starts with a 1 ref, so don't add a ref in the smart pointer
+ httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions());
- mErrorCert = NULL;
+ httpOpts->setTimeout(40L);
-// mCurlRequest->setopt(CURLOPT_VERBOSE, 1); // useful for debugging
- mCurlRequest->setopt(CURLOPT_NOSIGNAL, 1);
- mCurlRequest->setWriteCallback(&curlDownloadCallback, (void*)this);
- BOOL vefifySSLCert = !gSavedSettings.getBOOL("NoVerifySSLCert");
+ bool vefifySSLCert = !gSavedSettings.getBOOL("NoVerifySSLCert");
mCertStore = gSavedSettings.getString("CertStore");
- mCurlRequest->setopt(CURLOPT_SSL_VERIFYPEER, vefifySSLCert);
- mCurlRequest->setopt(CURLOPT_SSL_VERIFYHOST, vefifySSLCert ? 2 : 0);
- // Be a little impatient about establishing connections.
- mCurlRequest->setopt(CURLOPT_CONNECTTIMEOUT, 40L);
- mCurlRequest->setSSLCtxCallback(_sslCtxFunction, (void *)this);
- /* Setting the DNS cache timeout to -1 disables it completely.
- This might help with bug #503 */
- mCurlRequest->setopt(CURLOPT_DNS_CACHE_TIMEOUT, -1);
+ httpOpts->setSSLVerifyPeer( vefifySSLCert );
+ httpOpts->setSSLVerifyHost( vefifySSLCert ? 2 : 0);
- mCurlRequest->slist_append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_TEXT_XML);
+ // LLRefCounted starts with a 1 ref, so don't add a ref in the smart pointer
+ httpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders());
- if (useGzip)
- {
- mCurlRequest->setoptString(CURLOPT_ENCODING, "");
- }
+ httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_TEXT_XML);
+
+ ///* Setting the DNS cache timeout to -1 disables it completely.
+ //This might help with bug #503 */
+ //httpOpts->setDNSCacheTimeout(-1);
+
+ LLCore::BufferArray::ptr_t body = LLCore::BufferArray::ptr_t(new LLCore::BufferArray());
+
+ // TODO: See if there is a way to serialize to a preallocated buffer I'm
+ // not fond of the copy here.
+ int requestSize(0);
+ char * requestText = XMLRPC_REQUEST_ToXML(request, &requestSize);
+
+ body->append(requestText, requestSize);
- mRequestText = XMLRPC_REQUEST_ToXML(request, &mRequestTextSize);
- if (mRequestText)
- {
- mCurlRequest->setoptString(CURLOPT_POSTFIELDS, mRequestText);
- mCurlRequest->setopt(CURLOPT_POSTFIELDSIZE, mRequestTextSize);
- }
- else
- {
- setStatus(StatusOtherError);
- }
+ XMLRPC_Free(requestText);
+
+ mHandler = LLXMLRPCTransaction::Handler::ptr_t(new Handler( mHttpRequest, this ));
+
+ mPostH = mHttpRequest->requestPost(LLCore::HttpRequest::DEFAULT_POLICY_ID, 0,
+ mURI, body.get(), httpOpts, httpHeaders, mHandler.get());
- mCurlRequest->sendRequest(mURI);
}
@@ -361,28 +401,17 @@ LLXMLRPCTransaction::Impl::~Impl()
{
XMLRPC_RequestFree(mResponse, 1);
}
-
- if (mRequestText)
- {
- XMLRPC_Free(mRequestText);
- }
-
- delete mCurlRequest;
- mCurlRequest = NULL ;
}
bool LLXMLRPCTransaction::Impl::process()
{
- if(!mCurlRequest || !mCurlRequest->isValid())
+ if (!mPostH || !mHttpRequest)
{
- LL_WARNS() << "transaction failed." << LL_ENDL ;
-
- delete mCurlRequest ;
- mCurlRequest = NULL ;
- return true ; //failed, quit.
+ LL_WARNS() << "transaction failed." << LL_ENDL;
+ return true; //failed, quit.
}
- switch(mStatus)
+ switch (mStatus)
{
case LLXMLRPCTransaction::StatusComplete:
case LLXMLRPCTransaction::StatusCURLError:
@@ -391,93 +420,25 @@ bool LLXMLRPCTransaction::Impl::process()
{
return true;
}
-
+
case LLXMLRPCTransaction::StatusNotStarted:
{
setStatus(LLXMLRPCTransaction::StatusStarted);
break;
}
-
+
default:
- {
- // continue onward
- }
- }
-
- if(!mCurlRequest->wait())
- {
- return false ;
+ break;
}
- while(1)
- {
- CURLcode result;
- bool newmsg = mCurlRequest->getResult(&result, &mTransferInfo);
- if (newmsg)
- {
- if (result != CURLE_OK)
- {
- if ((result != CURLE_SSL_PEER_CERTIFICATE) &&
- (result != CURLE_SSL_CACERT))
- {
- // if we have a curl error that's not already been handled
- // (a non cert error), then generate the error message as
- // appropriate
- setCurlStatus(result);
-
- LL_WARNS() << "LLXMLRPCTransaction CURL error "
- << mCurlCode << ": " << mCurlRequest->getErrorString() << LL_ENDL;
- LL_WARNS() << "LLXMLRPCTransaction request URI: "
- << mURI << LL_ENDL;
- }
-
- return true;
- }
-
- setStatus(LLXMLRPCTransaction::StatusComplete);
+ LLCore::HttpStatus status = mHttpRequest->update(0);
- mResponse = XMLRPC_REQUEST_FromXML(
- mResponseText.data(), mResponseText.size(), NULL);
-
- bool hasError = false;
- bool hasFault = false;
- int faultCode = 0;
- std::string faultString;
-
- LLXMLRPCValue error(XMLRPC_RequestGetError(mResponse));
- if (error.isValid())
- {
- hasError = true;
- faultCode = error["faultCode"].asInt();
- faultString = error["faultString"].asString();
- }
- else if (XMLRPC_ResponseIsFault(mResponse))
- {
- hasFault = true;
- faultCode = XMLRPC_GetResponseFaultCode(mResponse);
- faultString = XMLRPC_GetResponseFaultString(mResponse);
- }
-
- if (hasError || hasFault)
- {
- setStatus(LLXMLRPCTransaction::StatusXMLRPCError);
-
- LL_WARNS() << "LLXMLRPCTransaction XMLRPC "
- << (hasError ? "error " : "fault ")
- << faultCode << ": "
- << faultString << LL_ENDL;
- LL_WARNS() << "LLXMLRPCTransaction request URI: "
- << mURI << LL_ENDL;
- }
-
- return true;
- }
- else
- {
- break; // done
- }
+ status = mHttpRequest->getStatus();
+ if (!status)
+ {
+ return false;
}
-
+
return false;
}
@@ -516,64 +477,51 @@ void LLXMLRPCTransaction::Impl::setStatus(EStatus status,
}
}
-void LLXMLRPCTransaction::Impl::setCurlStatus(CURLcode code)
+void LLXMLRPCTransaction::Impl::setHttpStatus(const LLCore::HttpStatus &status)
{
+ CURLcode code = static_cast<CURLcode>(status.toULong());
std::string message;
std::string uri = "http://secondlife.com/community/support.php";
-
+ LLURI failuri(mURI);
+
+
switch (code)
{
- case CURLE_COULDNT_RESOLVE_HOST:
- message =
- "DNS could not resolve the host name.\n"
- "Please verify that you can connect to the www.secondlife.com\n"
- "web site. If you can, but continue to receive this error,\n"
- "please go to the support section and report this problem.";
- break;
-
- case CURLE_SSL_PEER_CERTIFICATE:
- message =
- "The login server couldn't verify itself via SSL.\n"
- "If you continue to receive this error, please go\n"
- "to the Support section of the SecondLife.com web site\n"
- "and report the problem.";
- break;
-
- case CURLE_SSL_CACERT:
- case CURLE_SSL_CONNECT_ERROR:
- message =
- "Often this means that your computer\'s clock is set incorrectly.\n"
- "Please go to Control Panels and make sure the time and date\n"
- "are set correctly.\n"
- "Also check that your network and firewall are set up correctly.\n"
- "If you continue to receive this error, please go\n"
- "to the Support section of the SecondLife.com web site\n"
- "and report the problem.";
- break;
-
- default:
- break;
+ case CURLE_COULDNT_RESOLVE_HOST:
+ message =
+ std::string("DNS could not resolve the host name(") + failuri.hostName() + ").\n"
+ "Please verify that you can connect to the www.secondlife.com\n"
+ "web site. If you can, but continue to receive this error,\n"
+ "please go to the support section and report this problem.";
+ break;
+
+ case CURLE_SSL_PEER_CERTIFICATE:
+ message =
+ "The login server couldn't verify itself via SSL.\n"
+ "If you continue to receive this error, please go\n"
+ "to the Support section of the SecondLife.com web site\n"
+ "and report the problem.";
+ break;
+
+ case CURLE_SSL_CACERT:
+ case CURLE_SSL_CONNECT_ERROR:
+ message =
+ "Often this means that your computer\'s clock is set incorrectly.\n"
+ "Please go to Control Panels and make sure the time and date\n"
+ "are set correctly.\n"
+ "Also check that your network and firewall are set up correctly.\n"
+ "If you continue to receive this error, please go\n"
+ "to the Support section of the SecondLife.com web site\n"
+ "and report the problem.";
+ break;
+
+ default:
+ break;
}
-
+
mCurlCode = code;
setStatus(StatusCURLError, message, uri);
-}
-
-size_t LLXMLRPCTransaction::Impl::curlDownloadCallback(
- char* data, size_t size, size_t nmemb, void* user_data)
-{
- Impl& impl(*(Impl*)user_data);
-
- size_t n = size * nmemb;
- impl.mResponseText.append(data, n);
-
- if (impl.mStatus == LLXMLRPCTransaction::StatusStarted)
- {
- impl.setStatus(LLXMLRPCTransaction::StatusDownloading);
- }
-
- return n;
}
@@ -645,11 +593,11 @@ F64 LLXMLRPCTransaction::transferRate()
return 0.0L;
}
- double rate_bits_per_sec = impl.mTransferInfo.mSpeedDownload * 8.0;
+ double rate_bits_per_sec = impl.mTransferStats->mSpeedDownload * 8.0;
LL_INFOS("AppInit") << "Buffer size: " << impl.mResponseText.size() << " B" << LL_ENDL;
- LL_DEBUGS("AppInit") << "Transfer size: " << impl.mTransferInfo.mSizeDownload << " B" << LL_ENDL;
- LL_DEBUGS("AppInit") << "Transfer time: " << impl.mTransferInfo.mTotalTime << " s" << LL_ENDL;
+ LL_DEBUGS("AppInit") << "Transfer size: " << impl.mTransferStats->mSizeDownload << " B" << LL_ENDL;
+ LL_DEBUGS("AppInit") << "Transfer time: " << impl.mTransferStats->mTotalTime << " s" << LL_ENDL;
LL_INFOS("AppInit") << "Transfer rate: " << rate_bits_per_sec / 1000.0 << " Kb/s" << LL_ENDL;
return rate_bits_per_sec;
diff --git a/indra/newview/llxmlrpctransaction.h b/indra/newview/llxmlrpctransaction.h
index f2589c7f41..3a1c9c82b7 100755
--- a/indra/newview/llxmlrpctransaction.h
+++ b/indra/newview/llxmlrpctransaction.h
@@ -81,7 +81,7 @@ private:
class LLXMLRPCTransaction
- // an asynchronous request and respones via XML-RPC
+ // an asynchronous request and responses via XML-RPC
{
public:
LLXMLRPCTransaction(const std::string& uri,
@@ -127,7 +127,9 @@ public:
// only valid if StsatusComplete, otherwise 0.0
private:
+ class Handler;
class Impl;
+
Impl& impl;
};
diff --git a/indra/newview/tests/llcapabilitylistener_test.cpp b/indra/newview/tests/llcapabilitylistener_test.cpp
deleted file mode 100755
index bde991a01e..0000000000
--- a/indra/newview/tests/llcapabilitylistener_test.cpp
+++ /dev/null
@@ -1,271 +0,0 @@
-/**
- * @file llcapabilitylistener_test.cpp
- * @author Nat Goodspeed
- * @date 2008-12-31
- * @brief Test for llcapabilitylistener.cpp.
- *
- * $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$
- */
-
-// Precompiled header
-#include "../llviewerprecompiledheaders.h"
-// Own header
-#include "../llcapabilitylistener.h"
-// STL headers
-#include <stdexcept>
-#include <map>
-#include <vector>
-// std headers
-// external library headers
-#include "boost/bind.hpp"
-// other Linden headers
-#include "../test/lltut.h"
-#include "../llcapabilityprovider.h"
-#include "lluuid.h"
-#include "tests/networkio.h"
-#include "tests/commtest.h"
-#include "tests/wrapllerrs.h"
-#include "message.h"
-#include "stringize.h"
-
-#if defined(LL_WINDOWS)
-#pragma warning(disable: 4355) // using 'this' in base-class ctor initializer expr
-#endif
-
-/*****************************************************************************
-* TestCapabilityProvider
-*****************************************************************************/
-struct TestCapabilityProvider: public LLCapabilityProvider
-{
- TestCapabilityProvider(const LLHost& host):
- mHost(host)
- {}
-
- std::string getCapability(const std::string& cap) const
- {
- CapMap::const_iterator found = mCaps.find(cap);
- if (found != mCaps.end())
- return found->second;
- // normal LLViewerRegion lookup failure mode
- return "";
- }
- void setCapability(const std::string& cap, const std::string& url)
- {
- mCaps[cap] = url;
- }
- const LLHost& getHost() const { return mHost; }
- std::string getDescription() const { return "TestCapabilityProvider"; }
-
- LLHost mHost;
- typedef std::map<std::string, std::string> CapMap;
- CapMap mCaps;
-};
-
-/*****************************************************************************
-* Dummy LLMessageSystem methods
-*****************************************************************************/
-/*==========================================================================*|
-// This doesn't work because we're already linking in llmessage.a, and we get
-// duplicate-symbol errors from the linker. Perhaps if I wanted to go through
-// the exercise of providing dummy versions of every single symbol defined in
-// message.o -- maybe some day.
-typedef std::vector< std::pair<std::string, std::string> > StringPairVector;
-StringPairVector call_history;
-
-S32 LLMessageSystem::sendReliable(const LLHost& host)
-{
- call_history.push_back(StringPairVector::value_type("sendReliable", stringize(host)));
- return 0;
-}
-|*==========================================================================*/
-
-/*****************************************************************************
-* TUT
-*****************************************************************************/
-namespace tut
-{
- struct llcapears_data: public commtest_data
- {
- TestCapabilityProvider provider;
- LLCapabilityListener regionListener;
- LLEventPump& regionPump;
-
- llcapears_data():
- provider(host),
- regionListener("testCapabilityListener", NULL, provider, LLUUID(), LLUUID()),
- regionPump(regionListener.getCapAPI())
- {
- LLCurl::initClass();
- provider.setCapability("good", server + "capability-test");
- provider.setCapability("fail", server + "fail");
- }
- };
- typedef test_group<llcapears_data> llcapears_group;
- typedef llcapears_group::object llcapears_object;
- llcapears_group llsdmgr("llcapabilitylistener");
-
- template<> template<>
- void llcapears_object::test<1>()
- {
- LLSD request, body;
- body["data"] = "yes";
- request["payload"] = body;
- request["reply"] = replyPump.getName();
- request["error"] = errorPump.getName();
- std::string threw;
- try
- {
- WrapLLErrs capture;
- regionPump.post(request);
- }
- catch (const WrapLLErrs::FatalException& e)
- {
- threw = e.what();
- }
- ensure_contains("missing capability name", threw, "without 'message' key");
- }
-
- template<> template<>
- void llcapears_object::test<2>()
- {
- LLSD request, body;
- body["data"] = "yes";
- request["message"] = "good";
- request["payload"] = body;
- request["reply"] = replyPump.getName();
- request["error"] = errorPump.getName();
- regionPump.post(request);
- ensure("got response", netio.pump());
- ensure("success response", success);
- ensure_equals(result["reply"].asString(), "success");
-
- body["status"] = 499;
- body["reason"] = "custom error message";
- request["message"] = "fail";
- request["payload"] = body;
- regionPump.post(request);
- ensure("got response", netio.pump());
- ensure("failure response", ! success);
- ensure_equals(result["status"].asInteger(), body["status"].asInteger());
- ensure_equals(result["reason"].asString(), body["reason"].asString());
- }
-
- template<> template<>
- void llcapears_object::test<3>()
- {
- LLSD request, body;
- body["data"] = "yes";
- request["message"] = "unknown";
- request["payload"] = body;
- request["reply"] = replyPump.getName();
- request["error"] = errorPump.getName();
- std::string threw;
- try
- {
- WrapLLErrs capture;
- regionPump.post(request);
- }
- catch (const WrapLLErrs::FatalException& e)
- {
- threw = e.what();
- }
- ensure_contains("bad capability name", threw, "unsupported capability");
- }
-
- struct TestMapper: public LLCapabilityListener::CapabilityMapper
- {
- // Instantiator gets to specify whether mapper expects a reply.
- // I'd really like to be able to test CapabilityMapper::buildMessage()
- // functionality, too, but -- even though LLCapabilityListener accepts
- // the LLMessageSystem* that it passes to CapabilityMapper --
- // LLMessageSystem::sendReliable(const LLHost&) isn't virtual, so it's
- // not helpful to pass a subclass instance. I suspect that making any
- // LLMessageSystem methods virtual would provoke howls of outrage,
- // given how heavily it's used. Nor can I just provide a local
- // definition of LLMessageSystem::sendReliable(const LLHost&) because
- // we're already linking in the rest of message.o via llmessage.a, and
- // that produces duplicate-symbol link errors.
- TestMapper(const std::string& replyMessage = std::string()):
- LLCapabilityListener::CapabilityMapper("test", replyMessage)
- {}
- virtual void buildMessage(LLMessageSystem* msg,
- const LLUUID& agentID,
- const LLUUID& sessionID,
- const std::string& capabilityName,
- const LLSD& payload) const
- {
- msg->newMessageFast(_PREHASH_SetStartLocationRequest);
- msg->nextBlockFast( _PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, agentID);
- msg->addUUIDFast(_PREHASH_SessionID, sessionID);
- msg->nextBlockFast( _PREHASH_StartLocationData);
- // corrected by sim
- msg->addStringFast(_PREHASH_SimName, "");
- msg->addU32Fast(_PREHASH_LocationID, payload["HomeLocation"]["LocationId"].asInteger());
-/*==========================================================================*|
- msg->addVector3Fast(_PREHASH_LocationPos,
- ll_vector3_from_sdmap(payload["HomeLocation"]["LocationPos"]));
- msg->addVector3Fast(_PREHASH_LocationLookAt,
- ll_vector3_from_sdmap(payload["HomeLocation"]["LocationLookAt"]));
-|*==========================================================================*/
- }
- };
-
- template<> template<>
- void llcapears_object::test<4>()
- {
- TestMapper testMapper("WantReply");
- LLSD request, body;
- body["data"] = "yes";
- request["message"] = "test";
- request["payload"] = body;
- request["reply"] = replyPump.getName();
- request["error"] = errorPump.getName();
- std::string threw;
- try
- {
- WrapLLErrs capture;
- regionPump.post(request);
- }
- catch (const WrapLLErrs::FatalException& e)
- {
- threw = e.what();
- }
- ensure_contains("capability mapper wants reply", threw, "unimplemented support for reply message");
- }
-
- template<> template<>
- void llcapears_object::test<5>()
- {
- TestMapper testMapper;
- std::string threw;
- try
- {
- TestMapper testMapper2;
- }
- catch (const std::runtime_error& e)
- {
- threw = e.what();
- }
- ensure_contains("no dup cap mapper", threw, "DupCapMapper");
- }
-}
diff --git a/indra/newview/tests/llhttpretrypolicy_test.cpp b/indra/newview/tests/llhttpretrypolicy_test.cpp
index 25e6de46d9..8bd6cc2690 100755
--- a/indra/newview/tests/llhttpretrypolicy_test.cpp
+++ b/indra/newview/tests/llhttpretrypolicy_test.cpp
@@ -285,10 +285,10 @@ void RetryPolicyTestObject::test<7>()
ensure_approximately_equals_range("header 2", seconds_to_wait, 7.0F, 2.0F);
LLCore::HttpResponse *response;
- LLCore::HttpHeaders *headers;
+ LLCore::HttpHeaders::ptr_t headers;
response = new LLCore::HttpResponse();
- headers = new LLCore::HttpHeaders();
+ headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders());
response->setStatus(503);
response->setHeaders(headers);
headers->append(HTTP_IN_HEADER_RETRY_AFTER, std::string("600"));
@@ -299,7 +299,7 @@ void RetryPolicyTestObject::test<7>()
response->release();
response = new LLCore::HttpResponse();
- headers = new LLCore::HttpHeaders();
+ headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders());
response->setStatus(503);
response->setHeaders(headers);
time(&nowseconds);
diff --git a/indra/newview/tests/llmediadataclient_test.cpp b/indra/newview/tests/llmediadataclient_test.cpp
index 6f57daf151..61120686e4 100755
--- a/indra/newview/tests/llmediadataclient_test.cpp
+++ b/indra/newview/tests/llmediadataclient_test.cpp
@@ -106,7 +106,7 @@ const char *DATA = _DATA(VALID_OBJECT_ID,"1.0","true");
LLSD *gPostRecords = NULL;
F64 gMinimumInterestLevel = (F64)0.0;
-
+#if 0
// stubs:
void LLHTTPClient::post(
const std::string& url,
@@ -140,6 +140,7 @@ void LLHTTPClient::post(
}
responder->successResult(result);
}
+#endif
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 c49b0350e9..ea5014a59c 100755
--- a/indra/newview/tests/llremoteparcelrequest_test.cpp
+++ b/indra/newview/tests/llremoteparcelrequest_test.cpp
@@ -27,6 +27,7 @@
#include "linden_common.h"
#include "../test/lltut.h"
+#if 0
#include "../llremoteparcelrequest.h"
@@ -134,3 +135,4 @@ namespace tut
processor.processParcelInfoReply(gMessageSystem, NULL);
}
}
+#endif