diff options
-rw-r--r-- | indra/llmessage/llcorehttputil.cpp | 42 | ||||
-rw-r--r-- | indra/llmessage/llcorehttputil.h | 23 | ||||
-rwxr-xr-x | indra/newview/llaisapi.cpp | 698 | ||||
-rwxr-xr-x | indra/newview/llaisapi.h | 149 | ||||
-rwxr-xr-x | indra/newview/llviewerinventory.cpp | 55 |
5 files changed, 766 insertions, 201 deletions
diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp index a6ed287aeb..50c866f370 100644 --- a/indra/llmessage/llcorehttputil.cpp +++ b/indra/llmessage/llcorehttputil.cpp @@ -831,6 +831,44 @@ LLSD HttpCoroutineAdapter::deleteAndYield_(LLCore::HttpRequest::ptr_t &request, return results; } +LLSD HttpCoroutineAdapter::patchAndYield(LLCore::HttpRequest::ptr_t request, + const std::string & url, const LLSD & body, + LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers) +{ + LLEventStream replyPump(mAdapterName + "Reply", true); + HttpCoroHandler::ptr_t httpHandler = HttpCoroHandler::ptr_t(new HttpCoroLLSDHandler(replyPump)); + + return patchAndYield_(request, url, body, options, headers, httpHandler); +} + + +LLSD HttpCoroutineAdapter::patchAndYield_(LLCore::HttpRequest::ptr_t &request, + const std::string & url, const LLSD & body, + LLCore::HttpOptions::ptr_t &options, LLCore::HttpHeaders::ptr_t &headers, + HttpCoroHandler::ptr_t &handler) +{ + HttpRequestPumper pumper(request); + + checkDefaultHeaders(headers); + + // The HTTPCoroHandler does not self delete, so retrieval of a the contained + // pointer from the smart pointer is safe in this case. + LLCore::HttpHandle hhandle = requestPatchWithLLSD(request, + mPolicyId, mPriority, url, body, options, headers, + handler.get()); + + if (hhandle == LLCORE_HTTP_HANDLE_INVALID) + { + return HttpCoroutineAdapter::buildImmediateErrorResult(request, url); + } + + saveState(hhandle, request, handler); + LLSD results = llcoro::waitForEventOn(handler->getReplyPump()); + cleanState(); + //LL_INFOS() << "Results for transaction " << transactionId << LL_ENDL; + return results; +} + void HttpCoroutineAdapter::checkDefaultHeaders(LLCore::HttpHeaders::ptr_t &headers) { if (!headers) @@ -839,6 +877,10 @@ void HttpCoroutineAdapter::checkDefaultHeaders(LLCore::HttpHeaders::ptr_t &heade { headers->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_LLSD_XML); } + if (!headers->find(HTTP_OUT_HEADER_CONTENT_TYPE)) + { + headers->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML); + } if (!headers->find("X-SecondLife-UDP-Listen-Port") && gMessageSystem) { diff --git a/indra/llmessage/llcorehttputil.h b/indra/llmessage/llcorehttputil.h index 999fd5f90b..8fe2354d6b 100644 --- a/indra/llmessage/llcorehttputil.h +++ b/indra/llmessage/llcorehttputil.h @@ -456,6 +456,24 @@ public: LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()), LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders())); + + /// Execute a Post transaction on the supplied URL and yield execution of + /// the coroutine until a result is available. + /// + /// @Note: the request's smart pointer is passed by value so that it will + /// not be deallocated during the yield. + LLSD patchAndYield(LLCore::HttpRequest::ptr_t request, + const std::string & url, const LLSD & body, + LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()), + LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders())); + LLSD patchAndYield(LLCore::HttpRequest::ptr_t &request, + const std::string & url, const LLSD & body, + LLCore::HttpHeaders::ptr_t &headers) + { + return patchAndYield(request, url, body, + LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions()), headers); + } + /// void cancelYieldingOperation(); @@ -518,6 +536,11 @@ private: const std::string & url, LLCore::HttpOptions::ptr_t &options, LLCore::HttpHeaders::ptr_t &headers, HttpCoroHandler::ptr_t &handler); + LLSD patchAndYield_(LLCore::HttpRequest::ptr_t &request, + const std::string & url, const LLSD & body, + LLCore::HttpOptions::ptr_t &options, LLCore::HttpHeaders::ptr_t &headers, + HttpCoroHandler::ptr_t &handler); + static void trivialGetCoro(std::string url, LLCore::HttpRequest::policy_t policyId, completionCallback_t success, completionCallback_t failure); static void trivialPostCoro(std::string url, LLCore::HttpRequest::policy_t policyId, LLSD postData, completionCallback_t success, completionCallback_t failure); diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index 9d887a61f1..3565c04609 100755 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -37,6 +37,422 @@ #include "llviewercontrol.h" ///---------------------------------------------------------------------------- +#if 1 +/*static*/ +void AISAPI::CreateInventoryCommand(const LLUUID& parentId, const LLSD& newInventory, completion_t callback) +{ +#if 1 + std::string cap = getInvCap(); + if (cap.empty()) + { + LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; + return; + } + + LLUUID tid; + tid.generate(); + + std::string url = cap + std::string("/category/") + parentId.asString() + "?tid=" + tid.asString(); + LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; + + // I may be suffering from golden hammer here, but the first part of this bind + // is actually a static cast for &HttpCoroutineAdapter::postAndYield so that + // the compiler can identify the correct signature to select. + // + // Reads as follows: + // LLSD - method returning LLSD + // (LLCoreHttpUtil::HttpCoroutineAdapter::*) - pointer to member function of HttpCoroutineAdapter + // (LLCore::HttpRequest::ptr_t, const std::string &, const LLSD &, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t) - signature of method + // + invokationFn_t postFn = boost::bind( + // Humans ignore next line. It is just a cast. + static_cast<LLSD (LLCoreHttpUtil::HttpCoroutineAdapter::*)(LLCore::HttpRequest::ptr_t, const std::string &, const LLSD &, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t)> + //---- + (&LLCoreHttpUtil::HttpCoroutineAdapter::postAndYield), _1, _2, _3, _4, _5, _6); + + LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::InvokeAISCommandCoro, + _1, postFn, url, parentId, newInventory, callback)); +#else + LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::CreateInventoryCommandCoro, + _1, parentId, newInventory, callback)); + +#endif + EnqueueAISCommand("CreateInventory", proc); + +} + +/*static*/ +void AISAPI::SlamFolderCommand(const LLUUID& folderId, const LLSD& newInventory, completion_t callback) +{ +#if 1 + std::string cap = getInvCap(); + if (cap.empty()) + { + LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; + return; + } + + LLUUID tid; + tid.generate(); + + std::string url = cap + std::string("/category/") + folderId.asString() + "/links?tid=" + tid.asString(); + + // see comment above in CreateInventoryCommand + invokationFn_t putFn = boost::bind( + // Humans ignore next line. It is just a cast. + static_cast<LLSD(LLCoreHttpUtil::HttpCoroutineAdapter::*)(LLCore::HttpRequest::ptr_t, const std::string &, const LLSD &, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t)> + //---- + (&LLCoreHttpUtil::HttpCoroutineAdapter::putAndYield), _1, _2, _3, _4, _5, _6); + + LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::InvokeAISCommandCoro, + _1, putFn, url, folderId, newInventory, callback)); + +#else + LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::SlamFolderCommandCoro, + _1, folderId, newInventory, callback)); +#endif + + EnqueueAISCommand("SlamFolder", proc); +} + +void AISAPI::RemoveCategoryCommand(const LLUUID &categoryId, completion_t callback) +{ + std::string cap; + + cap = getInvCap(); + if (cap.empty()) + { + LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; + return; + } + + std::string url = cap + std::string("/category/") + categoryId.asString(); + LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; + + invokationFn_t delFn = boost::bind( + // Humans ignore next line. It is just a cast. + static_cast<LLSD(LLCoreHttpUtil::HttpCoroutineAdapter::*)(LLCore::HttpRequest::ptr_t, const std::string &, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t)> + //---- + (&LLCoreHttpUtil::HttpCoroutineAdapter::deleteAndYield), _1, _2, _3, _5, _6); + + LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::InvokeAISCommandCoro, + _1, delFn, url, categoryId, LLSD(), callback)); + + EnqueueAISCommand("RemoveCategory", proc); +} + +/*static*/ +void AISAPI::RemoveItemCommand(const LLUUID &itemId, completion_t callback) +{ +#if 1 + std::string cap; + + cap = getInvCap(); + if (cap.empty()) + { + LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; + return; + } + + std::string url = cap + std::string("/item/") + itemId.asString(); + LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; + + invokationFn_t delFn = boost::bind( + // Humans ignore next line. It is just a cast. + static_cast<LLSD(LLCoreHttpUtil::HttpCoroutineAdapter::*)(LLCore::HttpRequest::ptr_t, const std::string &, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t)> + //---- + (&LLCoreHttpUtil::HttpCoroutineAdapter::deleteAndYield), _1, _2, _3, _5, _6); + + LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::InvokeAISCommandCoro, + _1, delFn, url, itemId, LLSD(), callback)); + +#else + LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::RemoveItemCommandCoro, + _1, itemId, callback)); +#endif + + EnqueueAISCommand("RemoveItem", proc); +} + + +/*static*/ +void AISAPI::PurgeDescendentsCommand(const LLUUID &categoryId, completion_t callback) +{ + std::string cap; + + cap = getInvCap(); + if (cap.empty()) + { + LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; + return; + } + + std::string url = cap + std::string("/category/") + categoryId.asString() + "/children"; + LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; + + invokationFn_t delFn = boost::bind( + // Humans ignore next line. It is just a cast. + static_cast<LLSD(LLCoreHttpUtil::HttpCoroutineAdapter::*)(LLCore::HttpRequest::ptr_t, const std::string &, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t)> + //---- + (&LLCoreHttpUtil::HttpCoroutineAdapter::deleteAndYield), _1, _2, _3, _5, _6); + + LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::InvokeAISCommandCoro, + _1, delFn, url, categoryId, LLSD(), callback)); + + EnqueueAISCommand("PurgeDescendents", proc); +} + + +/*static*/ +void AISAPI::UpdateCategoryCommand(const LLUUID &categoryId, const LLSD &updates, completion_t callback) +{ + std::string cap; + + cap = getInvCap(); + if (cap.empty()) + { + LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; + return; + } + std::string url = cap + std::string("/category/") + categoryId.asString(); + + invokationFn_t patchFn = boost::bind( + // Humans ignore next line. It is just a cast. + static_cast<LLSD(LLCoreHttpUtil::HttpCoroutineAdapter::*)(LLCore::HttpRequest::ptr_t, const std::string &, const LLSD &, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t)> + //---- + (&LLCoreHttpUtil::HttpCoroutineAdapter::patchAndYield), _1, _2, _3, _4, _5, _6); + + LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::InvokeAISCommandCoro, + _1, patchFn, url, categoryId, updates, callback)); + + EnqueueAISCommand("UpdateCategory", proc); +} + +/*static*/ +void AISAPI::UpdateItemCommand(const LLUUID &itemId, const LLSD &updates, completion_t callback) +{ + + std::string cap; + + cap = getInvCap(); + if (cap.empty()) + { + LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; + return; + } + std::string url = cap + std::string("/item/") + itemId.asString(); + + invokationFn_t patchFn = boost::bind( + // Humans ignore next line. It is just a cast. + static_cast<LLSD(LLCoreHttpUtil::HttpCoroutineAdapter::*)(LLCore::HttpRequest::ptr_t, const std::string &, const LLSD &, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t)> + //---- + (&LLCoreHttpUtil::HttpCoroutineAdapter::patchAndYield), _1, _2, _3, _4, _5, _6); + + LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::InvokeAISCommandCoro, + _1, patchFn, url, itemId, updates, callback)); + + EnqueueAISCommand("UpdateItem", proc); +} + +/*static*/ +void AISAPI::EnqueueAISCommand(const std::string &procName, LLCoprocedureManager::CoProcedure_t proc) +{ + std::string procFullName = "AIS(" + procName + ")"; + LLCoprocedureManager::getInstance()->enqueueCoprocedure("AIS", procFullName, proc); + +} + +/*static*/ +std::string AISAPI::getInvCap() +{ + if (gAgent.getRegion()) + { + return gAgent.getRegion()->getCapability("InventoryAPIv3"); + } + + return std::string(); +} + +/*static*/ +std::string AISAPI::getLibCap() +{ + if (gAgent.getRegion()) + { + return gAgent.getRegion()->getCapability("LibraryAPIv3"); + } + return std::string(); +} + +/*static*/ +void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter, + invokationFn_t invoke, std::string url, + LLUUID targetId, LLSD body, completion_t callback) +{ + LLCore::HttpOptions::ptr_t httpOptions(new LLCore::HttpOptions); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest()); + LLCore::HttpHeaders::ptr_t httpHeaders; + + httpOptions->setTimeout(HTTP_REQUEST_EXPIRY_SECS); + + LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; + + LLSD result = invoke(httpAdapter, httpRequest, url, body, httpOptions, httpHeaders); + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status || !result.isMap()) + { + if (!result.isMap()) + { + status = LLCore::HttpStatus(HTTP_INTERNAL_ERROR, "Malformed response contents"); + } + LL_WARNS("Inventory") << "Inventory error: " << status.toString() << LL_ENDL; + LL_WARNS("Inventory") << ll_pretty_print_sd(result) << LL_ENDL; + } + + gInventory.onAISUpdateReceived("AISCommand", result); + + if (callback) + { // UUID always null + callback(LLUUID::null); + } + +} + +#if 0 +/*static*/ +void AISAPI::CreateInventoryCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter, LLUUID parentId, LLSD newInventory, completion_t callback) +{ + std::string cap; + LLCore::HttpOptions::ptr_t httpOptions(new LLCore::HttpOptions); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest()); + + httpOptions->setTimeout(HTTP_REQUEST_EXPIRY_SECS); + + cap = getInvCap(); + if (cap.empty()) + { + LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; + return; + } + + LLUUID tid; + tid.generate(); + + std::string url = cap + std::string("/category/") + parentId.asString() + "?tid=" + tid.asString(); + LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; + + LLSD result = httpAdapter->postAndYield(httpRequest, url, newInventory, httpOptions); + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status || !result.isMap()) + { + if (!result.isMap()) + { + status = LLCore::HttpStatus(HTTP_INTERNAL_ERROR, "Malformed response contents"); + } + LL_WARNS("Inventory") << "Inventory error: " << status.toString() << LL_ENDL; + LL_WARNS("Inventory") << ll_pretty_print_sd(result) << LL_ENDL; + } + + gInventory.onAISUpdateReceived("AISCommand", result); + + if (callback) + { // UUID always null + callback(LLUUID::null); + } + +} + +/*static*/ +void AISAPI::SlamFolderCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter, LLUUID folderId, LLSD newInventory, completion_t callback) +{ + std::string cap; + LLCore::HttpOptions::ptr_t httpOptions(new LLCore::HttpOptions); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest()); + + httpOptions->setTimeout(HTTP_REQUEST_EXPIRY_SECS); + + cap = getInvCap(); + if (cap.empty()) + { + LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; + return; + } + + LLUUID tid; + tid.generate(); + + std::string url = cap + std::string("/category/") + folderId.asString() + "/links?tid=" + tid.asString(); + + LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; + + LLSD result = httpAdapter->putAndYield(httpRequest, url, newInventory, httpOptions); + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status || !result.isMap()) + { + if (!result.isMap()) + { + status = LLCore::HttpStatus(HTTP_INTERNAL_ERROR, "Malformed response contents"); + } + LL_WARNS("Inventory") << "Inventory error: " << status.toString() << LL_ENDL; + LL_WARNS("Inventory") << ll_pretty_print_sd(result) << LL_ENDL; + } + + gInventory.onAISUpdateReceived("AISCommand", result); + + if (callback) + { // UUID always null + callback(LLUUID::null); + } + +} + +void AISAPI::RemoveItemCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter, LLUUID itemId, completion_t callback) +{ + std::string cap; + LLCore::HttpOptions::ptr_t httpOptions(new LLCore::HttpOptions); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest()); + + httpOptions->setTimeout(HTTP_REQUEST_EXPIRY_SECS); + + cap = getInvCap(); + if (cap.empty()) + { + LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; + return; + } + + std::string url = cap + std::string("/item/") + itemId.asString(); + LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; + + LLSD result = httpAdapter->deleteAndYield(httpRequest, url, httpOptions); + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status || !result.isMap()) + { + if (!result.isMap()) + { + status = LLCore::HttpStatus(HTTP_INTERNAL_ERROR, "Malformed response contents"); + } + LL_WARNS("Inventory") << "Inventory error: " << status.toString() << LL_ENDL; + LL_WARNS("Inventory") << ll_pretty_print_sd(result) << LL_ENDL; + } + + gInventory.onAISUpdateReceived("AISCommand", result); + + if (callback) + { // UUID always null + callback(LLUUID::null); + } +} +#endif +#endif +///---------------------------------------------------------------------------- /// Classes for AISv3 support. ///---------------------------------------------------------------------------- @@ -165,153 +581,153 @@ void AISCommand::getCapabilityNames(LLSD& capabilityNames) capabilityNames.append("LibraryAPIv3"); } -RemoveItemCommand::RemoveItemCommand(const LLUUID& item_id, - LLPointer<LLInventoryCallback> callback): - AISCommand(callback) -{ - std::string cap; - if (!getInvCap(cap)) - { - LL_WARNS() << "No cap found" << LL_ENDL; - return; - } - std::string url = cap + std::string("/item/") + item_id.asString(); - LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; - LLHTTPClient::ResponderPtr responder = this; - LLSD headers; - F32 timeout = HTTP_REQUEST_EXPIRY_SECS; - command_func_type cmd = boost::bind(&LLHTTPClient::del, url, responder, headers, timeout); - setCommandFunc(cmd); -} +// RemoveItemCommand::RemoveItemCommand(const LLUUID& item_id, +// LLPointer<LLInventoryCallback> callback): +// AISCommand(callback) +// { +// std::string cap; +// if (!getInvCap(cap)) +// { +// LL_WARNS() << "No cap found" << LL_ENDL; +// return; +// } +// std::string url = cap + std::string("/item/") + item_id.asString(); +// LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; +// LLHTTPClient::ResponderPtr responder = this; +// LLSD headers; +// F32 timeout = HTTP_REQUEST_EXPIRY_SECS; +// command_func_type cmd = boost::bind(&LLHTTPClient::del, url, responder, headers, timeout); +// setCommandFunc(cmd); +// } -RemoveCategoryCommand::RemoveCategoryCommand(const LLUUID& item_id, - LLPointer<LLInventoryCallback> callback): - AISCommand(callback) -{ - std::string cap; - if (!getInvCap(cap)) - { - LL_WARNS() << "No cap found" << LL_ENDL; - return; - } - std::string url = cap + std::string("/category/") + item_id.asString(); - LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; - LLHTTPClient::ResponderPtr responder = this; - LLSD headers; - F32 timeout = HTTP_REQUEST_EXPIRY_SECS; - command_func_type cmd = boost::bind(&LLHTTPClient::del, url, responder, headers, timeout); - setCommandFunc(cmd); -} +// RemoveCategoryCommand::RemoveCategoryCommand(const LLUUID& item_id, +// LLPointer<LLInventoryCallback> callback): +// AISCommand(callback) +// { +// std::string cap; +// if (!getInvCap(cap)) +// { +// LL_WARNS() << "No cap found" << LL_ENDL; +// return; +// } +// std::string url = cap + std::string("/category/") + item_id.asString(); +// LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; +// LLHTTPClient::ResponderPtr responder = this; +// LLSD headers; +// F32 timeout = HTTP_REQUEST_EXPIRY_SECS; +// command_func_type cmd = boost::bind(&LLHTTPClient::del, url, responder, headers, timeout); +// setCommandFunc(cmd); +// } -PurgeDescendentsCommand::PurgeDescendentsCommand(const LLUUID& item_id, - LLPointer<LLInventoryCallback> callback): - AISCommand(callback) -{ - std::string cap; - if (!getInvCap(cap)) - { - LL_WARNS() << "No cap found" << LL_ENDL; - return; - } - std::string url = cap + std::string("/category/") + item_id.asString() + "/children"; - LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; - LLCurl::ResponderPtr responder = this; - LLSD headers; - F32 timeout = HTTP_REQUEST_EXPIRY_SECS; - command_func_type cmd = boost::bind(&LLHTTPClient::del, url, responder, headers, timeout); - setCommandFunc(cmd); -} +// PurgeDescendentsCommand::PurgeDescendentsCommand(const LLUUID& item_id, +// LLPointer<LLInventoryCallback> callback): +// AISCommand(callback) +// { +// std::string cap; +// if (!getInvCap(cap)) +// { +// LL_WARNS() << "No cap found" << LL_ENDL; +// return; +// } +// std::string url = cap + std::string("/category/") + item_id.asString() + "/children"; +// LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; +// LLCurl::ResponderPtr responder = this; +// LLSD headers; +// F32 timeout = HTTP_REQUEST_EXPIRY_SECS; +// command_func_type cmd = boost::bind(&LLHTTPClient::del, url, responder, headers, timeout); +// setCommandFunc(cmd); +// } -UpdateItemCommand::UpdateItemCommand(const LLUUID& item_id, - const LLSD& updates, - LLPointer<LLInventoryCallback> callback): - mUpdates(updates), - AISCommand(callback) -{ - std::string cap; - if (!getInvCap(cap)) - { - LL_WARNS() << "No cap found" << LL_ENDL; - return; - } - std::string url = cap + std::string("/item/") + item_id.asString(); - LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; - LL_DEBUGS("Inventory") << "request: " << ll_pretty_print_sd(mUpdates) << LL_ENDL; - LLCurl::ResponderPtr responder = this; - LLSD headers; - headers["Content-Type"] = "application/llsd+xml"; - F32 timeout = HTTP_REQUEST_EXPIRY_SECS; - command_func_type cmd = boost::bind(&LLHTTPClient::patch, url, mUpdates, responder, headers, timeout); - setCommandFunc(cmd); -} +// UpdateItemCommand::UpdateItemCommand(const LLUUID& item_id, +// const LLSD& updates, +// LLPointer<LLInventoryCallback> callback): +// mUpdates(updates), +// AISCommand(callback) +// { +// std::string cap; +// if (!getInvCap(cap)) +// { +// LL_WARNS() << "No cap found" << LL_ENDL; +// return; +// } +// std::string url = cap + std::string("/item/") + item_id.asString(); +// LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; +// LL_DEBUGS("Inventory") << "request: " << ll_pretty_print_sd(mUpdates) << LL_ENDL; +// LLCurl::ResponderPtr responder = this; +// LLSD headers; +// headers["Content-Type"] = "application/llsd+xml"; +// F32 timeout = HTTP_REQUEST_EXPIRY_SECS; +// command_func_type cmd = boost::bind(&LLHTTPClient::patch, url, mUpdates, responder, headers, timeout); +// setCommandFunc(cmd); +// } -UpdateCategoryCommand::UpdateCategoryCommand(const LLUUID& cat_id, - const LLSD& updates, - LLPointer<LLInventoryCallback> callback): - mUpdates(updates), - AISCommand(callback) -{ - std::string cap; - if (!getInvCap(cap)) - { - LL_WARNS() << "No cap found" << LL_ENDL; - return; - } - std::string url = cap + std::string("/category/") + cat_id.asString(); - LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; - LLCurl::ResponderPtr responder = this; - LLSD headers; - headers["Content-Type"] = "application/llsd+xml"; - F32 timeout = HTTP_REQUEST_EXPIRY_SECS; - command_func_type cmd = boost::bind(&LLHTTPClient::patch, url, mUpdates, responder, headers, timeout); - setCommandFunc(cmd); -} +// UpdateCategoryCommand::UpdateCategoryCommand(const LLUUID& cat_id, +// const LLSD& updates, +// LLPointer<LLInventoryCallback> callback): +// mUpdates(updates), +// AISCommand(callback) +// { +// std::string cap; +// if (!getInvCap(cap)) +// { +// LL_WARNS() << "No cap found" << LL_ENDL; +// return; +// } +// std::string url = cap + std::string("/category/") + cat_id.asString(); +// LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; +// LLCurl::ResponderPtr responder = this; +// LLSD headers; +// headers["Content-Type"] = "application/llsd+xml"; +// F32 timeout = HTTP_REQUEST_EXPIRY_SECS; +// command_func_type cmd = boost::bind(&LLHTTPClient::patch, url, mUpdates, responder, headers, timeout); +// setCommandFunc(cmd); +// } -CreateInventoryCommand::CreateInventoryCommand(const LLUUID& parent_id, - const LLSD& new_inventory, - LLPointer<LLInventoryCallback> callback): - mNewInventory(new_inventory), - AISCommand(callback) -{ - std::string cap; - if (!getInvCap(cap)) - { - LL_WARNS() << "No cap found" << LL_ENDL; - return; - } - LLUUID tid; - tid.generate(); - std::string url = cap + std::string("/category/") + parent_id.asString() + "?tid=" + tid.asString(); - LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; - LLCurl::ResponderPtr responder = this; - LLSD headers; - headers["Content-Type"] = "application/llsd+xml"; - F32 timeout = HTTP_REQUEST_EXPIRY_SECS; - command_func_type cmd = boost::bind(&LLHTTPClient::post, url, mNewInventory, responder, headers, timeout); - setCommandFunc(cmd); -} +// CreateInventoryCommand::CreateInventoryCommand(const LLUUID& parent_id, +// const LLSD& new_inventory, +// LLPointer<LLInventoryCallback> callback): +// mNewInventory(new_inventory), +// AISCommand(callback) +// { +// std::string cap; +// if (!getInvCap(cap)) +// { +// LL_WARNS() << "No cap found" << LL_ENDL; +// return; +// } +// LLUUID tid; +// tid.generate(); +// std::string url = cap + std::string("/category/") + parent_id.asString() + "?tid=" + tid.asString(); +// LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; +// LLCurl::ResponderPtr responder = this; +// LLSD headers; +// headers["Content-Type"] = "application/llsd+xml"; +// F32 timeout = HTTP_REQUEST_EXPIRY_SECS; +// command_func_type cmd = boost::bind(&LLHTTPClient::post, url, mNewInventory, responder, headers, timeout); +// setCommandFunc(cmd); +// } -SlamFolderCommand::SlamFolderCommand(const LLUUID& folder_id, const LLSD& contents, LLPointer<LLInventoryCallback> callback): - mContents(contents), - AISCommand(callback) -{ - std::string cap; - if (!getInvCap(cap)) - { - LL_WARNS() << "No cap found" << LL_ENDL; - return; - } - LLUUID tid; - tid.generate(); - std::string url = cap + std::string("/category/") + folder_id.asString() + "/links?tid=" + tid.asString(); - LL_INFOS() << url << LL_ENDL; - LLCurl::ResponderPtr responder = this; - LLSD headers; - headers["Content-Type"] = "application/llsd+xml"; - F32 timeout = HTTP_REQUEST_EXPIRY_SECS; - command_func_type cmd = boost::bind(&LLHTTPClient::put, url, mContents, responder, headers, timeout); - setCommandFunc(cmd); -} +// SlamFolderCommand::SlamFolderCommand(const LLUUID& folder_id, const LLSD& contents, LLPointer<LLInventoryCallback> callback): +// mContents(contents), +// AISCommand(callback) +// { +// std::string cap; +// if (!getInvCap(cap)) +// { +// LL_WARNS() << "No cap found" << LL_ENDL; +// return; +// } +// LLUUID tid; +// tid.generate(); +// std::string url = cap + std::string("/category/") + folder_id.asString() + "/links?tid=" + tid.asString(); +// LL_INFOS() << url << LL_ENDL; +// LLCurl::ResponderPtr responder = this; +// LLSD headers; +// headers["Content-Type"] = "application/llsd+xml"; +// F32 timeout = HTTP_REQUEST_EXPIRY_SECS; +// command_func_type cmd = boost::bind(&LLHTTPClient::put, url, mContents, responder, headers, timeout); +// setCommandFunc(cmd); +// } CopyLibraryCategoryCommand::CopyLibraryCategoryCommand(const LLUUID& source_id, const LLUUID& dest_id, diff --git a/indra/newview/llaisapi.h b/indra/newview/llaisapi.h index 5a2ec94af9..ebb952a3ec 100755 --- a/indra/newview/llaisapi.h +++ b/indra/newview/llaisapi.h @@ -35,6 +35,41 @@ #include "llhttpclient.h" #include "llhttpretrypolicy.h" #include "llviewerinventory.h" +#include "llcorehttputil.h" +#include "llcoproceduremanager.h" + +#if 1 +class AISAPI +{ +public: + typedef boost::function<void(const LLUUID &invItem)> completion_t; + + static void CreateInventoryCommand(const LLUUID& parentId, const LLSD& newInventory, completion_t callback); + static void SlamFolderCommand(const LLUUID& folderId, const LLSD& newInventory, completion_t callback); + static void RemoveCategoryCommand(const LLUUID &categoryId, completion_t callback); + static void RemoveItemCommand(const LLUUID &itemId, completion_t callback); + static void PurgeDescendentsCommand(const LLUUID &categoryId, completion_t callback); + static void UpdateCategoryCommand(const LLUUID &categoryId, const LLSD &updates, completion_t callback); + static void UpdateItemCommand(const LLUUID &itemId, const LLSD &updates, completion_t callback); + +private: + typedef boost::function < LLSD (LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t, LLCore::HttpRequest::ptr_t, + const std::string, LLSD, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t) > invokationFn_t; + + static void EnqueueAISCommand(const std::string &procName, LLCoprocedureManager::CoProcedure_t proc); + + static std::string getInvCap(); + static std::string getLibCap(); + + static void InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter, invokationFn_t invoke, std::string url, LLUUID targetId, LLSD body, completion_t callback); + +#if 0 + static void CreateInventoryCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter, LLUUID parentId, LLSD newInventory, completion_t callback); + static void SlamFolderCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter, LLUUID folderId, LLSD newInventory, completion_t callback); + static void RemoveItemCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter, LLUUID itemId, completion_t callback); +#endif +}; +#endif class AISCommand: public LLHTTPClient::Responder { @@ -71,55 +106,55 @@ private: LLPointer<LLInventoryCallback> mCallback; }; -class RemoveItemCommand: public AISCommand -{ -public: - RemoveItemCommand(const LLUUID& item_id, - LLPointer<LLInventoryCallback> callback); -}; - -class RemoveCategoryCommand: public AISCommand -{ -public: - RemoveCategoryCommand(const LLUUID& item_id, - LLPointer<LLInventoryCallback> callback); -}; - -class PurgeDescendentsCommand: public AISCommand -{ -public: - PurgeDescendentsCommand(const LLUUID& item_id, - LLPointer<LLInventoryCallback> callback); -}; - -class UpdateItemCommand: public AISCommand -{ -public: - UpdateItemCommand(const LLUUID& item_id, - const LLSD& updates, - LLPointer<LLInventoryCallback> callback); -private: - LLSD mUpdates; -}; - -class UpdateCategoryCommand: public AISCommand -{ -public: - UpdateCategoryCommand(const LLUUID& cat_id, - const LLSD& updates, - LLPointer<LLInventoryCallback> callback); -private: - LLSD mUpdates; -}; - -class SlamFolderCommand: public AISCommand -{ -public: - SlamFolderCommand(const LLUUID& folder_id, const LLSD& contents, LLPointer<LLInventoryCallback> callback); - -private: - LLSD mContents; -}; +// class RemoveItemCommand: public AISCommand +// { +// public: +// RemoveItemCommand(const LLUUID& item_id, +// LLPointer<LLInventoryCallback> callback); +// }; + +// class RemoveCategoryCommand: public AISCommand +// { +// public: +// RemoveCategoryCommand(const LLUUID& item_id, +// LLPointer<LLInventoryCallback> callback); +// }; + +// class PurgeDescendentsCommand: public AISCommand +// { +// public: +// PurgeDescendentsCommand(const LLUUID& item_id, +// LLPointer<LLInventoryCallback> callback); +// }; + +// class UpdateItemCommand: public AISCommand +// { +// public: +// UpdateItemCommand(const LLUUID& item_id, +// const LLSD& updates, +// LLPointer<LLInventoryCallback> callback); +// private: +// LLSD mUpdates; +// }; + +// class UpdateCategoryCommand: public AISCommand +// { +// public: +// UpdateCategoryCommand(const LLUUID& cat_id, +// const LLSD& updates, +// LLPointer<LLInventoryCallback> callback); +// private: +// LLSD mUpdates; +// }; + +// class SlamFolderCommand: public AISCommand +// { +// public: +// SlamFolderCommand(const LLUUID& folder_id, const LLSD& contents, LLPointer<LLInventoryCallback> callback); +// +// private: +// LLSD mContents; +// }; class CopyLibraryCategoryCommand: public AISCommand { @@ -130,14 +165,14 @@ protected: /* virtual */ bool getResponseUUID(const LLSD& content, LLUUID& id); }; -class CreateInventoryCommand: public AISCommand -{ -public: - CreateInventoryCommand(const LLUUID& parent_id, const LLSD& new_inventory, LLPointer<LLInventoryCallback> callback); - -private: - LLSD mNewInventory; -}; +// class CreateInventoryCommand: public AISCommand +// { +// public: +// CreateInventoryCommand(const LLUUID& parent_id, const LLSD& new_inventory, LLPointer<LLInventoryCallback> callback); +// +// private: +// LLSD mNewInventory; +// }; class AISUpdate { diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index f6db5d5d77..19254c0e23 100755 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -79,6 +79,15 @@ static const char * const LOG_INV("Inventory"); static const char * const LOG_LOCAL("InventoryLocalize"); static const char * const LOG_NOTECARD("copy_inventory_from_notecard"); +#if 1 +// temp code in transition +void doInventoryCb(LLPointer<LLInventoryCallback> cb, LLUUID id) +{ + if (cb.notNull()) + cb->fire(id); +} +#endif + ///---------------------------------------------------------------------------- /// Helper class to store special inventory item names and their localized values. ///---------------------------------------------------------------------------- @@ -1255,8 +1264,13 @@ void link_inventory_array(const LLUUID& category, { LLSD new_inventory = LLSD::emptyMap(); new_inventory["links"] = links; - LLPointer<AISCommand> cmd_ptr = new CreateInventoryCommand(category, new_inventory, cb); - ais_ran = cmd_ptr->run_command(); +#if 1 + AISAPI::completion_t compl = boost::bind(&doInventoryCb, cb, _1); + AISAPI::CreateInventoryCommand(category, new_inventory, compl); +#else + LLPointer<AISCommand> cmd_ptr = new CreateInventoryCommand(category, new_inventory, cb); + ais_ran = cmd_ptr->run_command(); +#endif } if (!ais_ran) @@ -1331,8 +1345,13 @@ void update_inventory_item( updates.erase("shadow_id"); updates["hash_id"] = update_item->getTransactionID(); } +#if 1 + AISAPI::completion_t compl = boost::bind(&doInventoryCb, cb, _1); + AISAPI::UpdateItemCommand(item_id, updates, compl); +#else LLPointer<AISCommand> cmd_ptr = new UpdateItemCommand(item_id, updates, cb); ais_ran = cmd_ptr->run_command(); +#endif } if (!ais_ran) { @@ -1373,8 +1392,13 @@ void update_inventory_item( bool ais_ran = false; if (AISCommand::isAPIAvailable()) { +#if 1 + AISAPI::completion_t compl = boost::bind(&doInventoryCb, cb, _1); + AISAPI::UpdateItemCommand(item_id, updates, compl); +#else LLPointer<AISCommand> cmd_ptr = new UpdateItemCommand(item_id, updates, cb); ais_ran = cmd_ptr->run_command(); +#endif } if (!ais_ran) { @@ -1429,8 +1453,13 @@ void update_inventory_category( if (AISCommand::isAPIAvailable()) { LLSD new_llsd = new_cat->asLLSD(); +#if 1 + AISAPI::completion_t compl = boost::bind(&doInventoryCb, cb, _1); + AISAPI::UpdateCategoryCommand(cat_id, new_llsd, compl); +#else LLPointer<AISCommand> cmd_ptr = new UpdateCategoryCommand(cat_id, new_llsd, cb); cmd_ptr->run_command(); +#endif } else // no cap { @@ -1494,8 +1523,13 @@ void remove_inventory_item( LL_DEBUGS(LOG_INV) << "item_id: [" << item_id << "] name " << obj->getName() << LL_ENDL; if (AISCommand::isAPIAvailable()) { +#if 1 + AISAPI::completion_t compl = boost::bind(&doInventoryCb, cb, _1); + AISAPI::RemoveItemCommand(item_id, compl); +#else LLPointer<AISCommand> cmd_ptr = new RemoveItemCommand(item_id, cb); cmd_ptr->run_command(); +#endif if (immediate_delete) { @@ -1570,8 +1604,13 @@ void remove_inventory_category( } if (AISCommand::isAPIAvailable()) { +#if 1 + AISAPI::completion_t compl = boost::bind(&doInventoryCb, cb, _1); + AISAPI::RemoveCategoryCommand(cat_id, compl); +#else LLPointer<AISCommand> cmd_ptr = new RemoveCategoryCommand(cat_id, cb); cmd_ptr->run_command(); +#endif } else // no cap { @@ -1673,8 +1712,13 @@ void purge_descendents_of(const LLUUID& id, LLPointer<LLInventoryCallback> cb) { if (AISCommand::isAPIAvailable()) { - LLPointer<AISCommand> cmd_ptr = new PurgeDescendentsCommand(id, cb); +#if 1 + AISAPI::completion_t compl = boost::bind(&doInventoryCb, cb, _1); + AISAPI::PurgeDescendentsCommand(id, compl); +#else + LLPointer<AISCommand> cmd_ptr = new PurgeDescendentsCommand(id, cb); cmd_ptr->run_command(); +#endif } else // no cap { @@ -1825,8 +1869,13 @@ void slam_inventory_folder(const LLUUID& folder_id, { LL_DEBUGS(LOG_INV) << "using AISv3 to slam folder, id " << folder_id << " new contents: " << ll_pretty_print_sd(contents) << LL_ENDL; +#if 1 + AISAPI::completion_t compl = boost::bind(&doInventoryCb, cb, _1); + AISAPI::SlamFolderCommand(folder_id, contents, compl); +#else LLPointer<AISCommand> cmd_ptr = new SlamFolderCommand(folder_id, contents, cb); cmd_ptr->run_command(); +#endif } else // no cap { |