summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorMonty Brandenberg <monty@lindenlab.com>2014-08-26 18:33:14 -0400
committerMonty Brandenberg <monty@lindenlab.com>2014-08-26 18:33:14 -0400
commitbbf9de9c6717f38a77a39d42d8493d275d558db9 (patch)
tree64fd0b76e3ca4961e4b0b338b0f05d42a03c0882 /indra
parentb64ef2ecd4af5265483527f2ef030554133ab137 (diff)
Bring better error handling to inventory item and folder fetching.
First, introduced some LLSD-based interfaces to the llcorehttp code using utils classes (in llcorehttputil). I've kept LLSD out of the llcorehttp library up to now and will continue to do that. Functions provide a requestPost based on LLSD body and conversion utils for HttpResponse-to-LLSD and HttpResponse-to-string conversions. Inventory fetch operations now do more thorough error checking including 200-with-error status checking. Still do retry forever on folders though I don't like that.
Diffstat (limited to 'indra')
-rwxr-xr-xindra/llmessage/CMakeLists.txt4
-rw-r--r--indra/llmessage/llcorehttputil.cpp137
-rw-r--r--indra/llmessage/llcorehttputil.h115
-rwxr-xr-xindra/newview/llinventorymodel.cpp76
-rwxr-xr-xindra/newview/llinventorymodelbackgroundfetch.cpp115
5 files changed, 386 insertions, 61 deletions
diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt
index 8bd134dc84..40eddcb0ab 100755
--- a/indra/llmessage/CMakeLists.txt
+++ b/indra/llmessage/CMakeLists.txt
@@ -6,6 +6,7 @@ include(00-Common)
include(GoogleMock)
include(LLAddBuildTest)
include(LLCommon)
+include(LLCoreHttp)
include(LLMath)
include(LLMessage)
include(LLVFS)
@@ -18,6 +19,7 @@ include_directories (${CMAKE_CURRENT_SOURCE_DIR})
include_directories(
${LLCOMMON_INCLUDE_DIRS}
+ ${LLCOREHTTP_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLMESSAGE_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
@@ -36,6 +38,7 @@ set(llmessage_SOURCE_FILES
llchainio.cpp
llcircuit.cpp
llclassifiedflags.cpp
+ llcorehttputil.cpp
llcurl.cpp
lldatapacker.cpp
lldispatcher.cpp
@@ -124,6 +127,7 @@ set(llmessage_HEADER_FILES
llcipher.h
llcircuit.h
llclassifiedflags.h
+ llcorehttputil.h
llcurl.h
lldatapacker.h
lldbstrings.h
diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp
new file mode 100644
index 0000000000..8d09aac971
--- /dev/null
+++ b/indra/llmessage/llcorehttputil.cpp
@@ -0,0 +1,137 @@
+/**
+ * @file llcorehttputil.cpp
+ * @date 2014-08-25
+ * @brief Implementation of adapter and utility classes expanding the llcorehttp interfaces.
+ *
+ * $LicenseInfo:firstyear=2014&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2014, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include <sstream>
+
+#include "llcorehttputil.h"
+#include "llsdserialize.h"
+
+
+using namespace LLCore;
+
+
+namespace LLCoreHttpUtil
+{
+
+
+bool responseToLLSD(HttpResponse * response, bool log, LLSD & out_llsd)
+{
+ // Convert response to LLSD
+ BufferArray * body(response->getBody());
+ if (! body || ! body->size())
+ {
+ return false;
+ }
+
+ LLCore::BufferArrayStream bas(body);
+ LLSD body_llsd;
+ S32 parse_status(LLSDSerialize::fromXML(body_llsd, bas, log));
+ if (LLSDParser::PARSE_FAILURE == parse_status){
+ return false;
+ }
+ out_llsd = body_llsd;
+ return true;
+}
+
+
+HttpHandle requestPostWithLLSD(HttpRequest * request,
+ HttpRequest::policy_t policy_id,
+ HttpRequest::priority_t priority,
+ const std::string & url,
+ const LLSD & body,
+ HttpOptions * options,
+ HttpHeaders * headers,
+ HttpHandler * handler)
+{
+ HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
+
+ BufferArray * ba = new BufferArray();
+ BufferArrayStream bas(ba);
+ LLSDSerialize::toXML(body, bas);
+
+ handle = request->requestPost(policy_id,
+ priority,
+ url,
+ ba,
+ options,
+ headers,
+ handler);
+ ba->release();
+ return handle;
+}
+
+
+std::string responseToString(LLCore::HttpResponse * response)
+{
+ static const std::string empty("[Empty]");
+
+ if (! response)
+ {
+ return empty;
+ }
+
+ BufferArray * body(response->getBody());
+ if (! body || ! body->size())
+ {
+ return empty;
+ }
+
+ // Attempt to parse as LLSD regardless of content-type
+ LLSD body_llsd;
+ if (responseToLLSD(response, false, body_llsd))
+ {
+ std::ostringstream tmp;
+
+ LLSDSerialize::toPrettyNotation(body_llsd, tmp);
+ std::size_t temp_len(tmp.tellp());
+
+ if (temp_len)
+ {
+ return tmp.str().substr(0, std::min(temp_len, std::size_t(1024)));
+ }
+ }
+ else
+ {
+ // *TODO: More elaborate forms based on Content-Type as needed.
+ char content[1024];
+
+ size_t len(body->read(0, content, sizeof(content)));
+ if (len)
+ {
+ return std::string(content, 0, len);
+ }
+ }
+
+ // Default
+ return empty;
+}
+
+
+} // end namespace LLCoreHttpUtil
+
diff --git a/indra/llmessage/llcorehttputil.h b/indra/llmessage/llcorehttputil.h
new file mode 100644
index 0000000000..d40172bc7a
--- /dev/null
+++ b/indra/llmessage/llcorehttputil.h
@@ -0,0 +1,115 @@
+/**
+ * @file llcorehttputil.h
+ * @date 2014-08-25
+ * @brief Adapter and utility classes expanding the llcorehttp interfaces.
+ *
+ * $LicenseInfo:firstyear=2014&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2014, 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_LLCOREHTTPUTIL_H
+#define LL_LLCOREHTTPUTIL_H
+
+#include <string>
+
+#include "httpcommon.h"
+#include "httprequest.h"
+#include "httpresponse.h"
+#include "httpheaders.h"
+#include "httpoptions.h"
+#include "httphandler.h"
+#include "bufferarray.h"
+#include "bufferstream.h"
+#include "llsd.h"
+
+///
+/// The base llcorehttp library implements many HTTP idioms
+/// used in the viewer but not all. That library intentionally
+/// avoids the use of LLSD and its conventions which aren't
+/// universally applicable. This module, using namespace
+/// LLCoreHttpUtil, provides the additional helper functions
+/// that support idiomatic LLSD transport via the newer
+/// llcorehttp library.
+///
+namespace LLCoreHttpUtil
+{
+
+/// Attempt to convert a response object's contents to LLSD.
+/// It is expected that the response body will be of non-zero
+/// length on input but basic checks will be performed and
+/// and error (false status) returned if there is no data.
+/// If there is data but it cannot be successfully parsed,
+/// an error is also returned. If successfully parsed,
+/// the output LLSD object, out_llsd, is written with the
+/// result and true is returned.
+///
+/// @arg response Response object as returned in
+/// in an HttpHandler onCompleted() callback.
+/// @arg log If true, LLSD parser will emit errors
+/// as LL_INFOS-level messages as it parses.
+/// Otherwise, it *should* be a quiet parse.
+/// @arg out_llsd Output LLSD object written only upon
+/// successful parse of the response object.
+///
+/// @return Returns true (and writes to out_llsd) if
+/// parse was successful. False otherwise.
+///
+bool responseToLLSD(LLCore::HttpResponse * response,
+ bool log,
+ LLSD & out_llsd);
+
+/// Create a std::string representation of a response object
+/// suitable for logging. Mainly intended for logging of
+/// failures and debug information. This won't be fast,
+/// just adequate.
+std::string responseToString(LLCore::HttpResponse * response);
+
+
+/// Issue a standard HttpRequest::requestPost() call but using
+/// and LLSD object as the request body. Conventions are the
+/// same as with that method. Caller is expected to provide
+/// an HttpHeaders object with a correct 'Content-Type:' header.
+/// One will not be provided by this call. You might look after
+/// the 'Accept:' header as well.
+///
+/// @return If request is successfully issued, the
+/// HttpHandle representing the request.
+/// On error, LLCORE_HTTP_HANDLE_INVALID
+/// is returned and caller can fetch detailed
+/// status with the getStatus() method on the
+/// request object. In case of error, no
+/// request is queued and caller may need to
+/// perform additional cleanup such as freeing
+/// a now-useless HttpHandler object.
+///
+LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest * request,
+ LLCore::HttpRequest::policy_t policy_id,
+ LLCore::HttpRequest::priority_t priority,
+ const std::string & url,
+ const LLSD & body,
+ LLCore::HttpOptions * options,
+ LLCore::HttpHeaders * headers,
+ LLCore::HttpHandler * handler);
+
+} // end namespace LLCoreHttpUtil
+
+
+#endif // LL_LLCOREHTTPUTIL_H
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 2dd31f047f..5273fb6d96 100755
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -55,7 +55,7 @@
#include "llsdutil.h"
#include "bufferarray.h"
#include "bufferstream.h"
-#include "llsdserialize.h"
+#include "llcorehttputil.h"
//#define DIFF_INVENTORY_FILES
#ifdef DIFF_INVENTORY_FILES
@@ -75,12 +75,6 @@ BOOL LLInventoryModel::sFirstTimeInViewer2 = TRUE;
static const char CACHE_FORMAT_STRING[] = "%s.inv";
static const char * const LOG_INV("Inventory");
-static std::string dumpResponse()
-{
- return std::string("ADD SOMETHING MEANINGFUL HERE");
-}
-
-
struct InventoryIDPtrLess
{
bool operator()(const LLViewerInventoryCategory* i1, const LLViewerInventoryCategory* i2) const
@@ -2468,18 +2462,15 @@ LLCore::HttpHandle LLInventoryModel::requestPost(bool foreground,
LLCore::HttpRequest * request(foreground ? mHttpRequestFG : mHttpRequestBG);
LLCore::HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
- LLCore::BufferArray * ba = new LLCore::BufferArray;
- LLCore::BufferArrayStream bas(ba);
- LLSDSerialize::toXML(body, bas);
- handle = request->requestPost(mHttpPolicyClass,
- (foreground ? mHttpPriorityFG : mHttpPriorityBG),
- url,
- ba,
- mHttpOptions,
- mHttpHeaders,
- handler);
- ba->release();
+ handle = LLCoreHttpUtil::requestPostWithLLSD(request,
+ mHttpPolicyClass,
+ (foreground ? mHttpPriorityFG : mHttpPriorityBG),
+ url,
+ body,
+ mHttpOptions,
+ mHttpHeaders,
+ handler);
if (LLCORE_HTTP_HANDLE_INVALID == handle)
{
LLCore::HttpStatus status(request->getStatus());
@@ -3981,6 +3972,7 @@ void LLInventoryModel::FetchItemHttpHandler::onCompleted(LLCore::HttpHandle hand
LLCore::HttpResponse * response)
{
LLCore::HttpStatus status(response->getStatus());
+ // status = LLCore::HttpStatus(404); // Dev tool to force error handling
if (! status)
{
processFailure(status, response);
@@ -3988,23 +3980,41 @@ void LLInventoryModel::FetchItemHttpHandler::onCompleted(LLCore::HttpHandle hand
else
{
LLCore::BufferArray * body(response->getBody());
+ // body = NULL; // Dev tool to force error handling
if (! body || ! body->size())
{
LL_WARNS(LOG_INV) << "Missing data in inventory item query." << LL_ENDL;
processFailure("HTTP response for inventory item query missing body", response);
goto only_exit;
}
-
- LLCore::BufferArrayStream bas(body);
+
+ // body->write(0, "Garbage Response", 16); // Dev tool to force error handling
LLSD body_llsd;
- S32 parse_status(LLSDSerialize::fromXML(body_llsd, bas));
- if (LLSDParser::PARSE_FAILURE == parse_status)
+ if (! LLCoreHttpUtil::responseToLLSD(response, true, body_llsd))
{
// INFOS-level logging will occur on the parsed failure
processFailure("HTTP response for inventory item query has malformed LLSD", response);
goto only_exit;
}
+ // Expect top-level structure to be a map
+ // body_llsd = LLSD::emptyArray(); // Dev tool to force error handling
+ if (! body_llsd.isMap())
+ {
+ processFailure("LLSD response for inventory item not a map", response);
+ goto only_exit;
+ }
+
+ // Check for 200-with-error failures
+ // body_llsd["error"] = LLSD::emptyMap(); // Dev tool to force error handling
+ // body_llsd["error"]["identifier"] = "Development";
+ // body_llsd["error"]["message"] = "You left development code in the viewer";
+ if (body_llsd.has("error"))
+ {
+ processFailure("Inventory application error (200-with-error)", response);
+ goto only_exit;
+ }
+
// Okay, process data if possible
processData(body_llsd, response);
}
@@ -4016,12 +4026,6 @@ only_exit:
void LLInventoryModel::FetchItemHttpHandler::processData(LLSD & content, LLCore::HttpResponse * response)
{
- if (! content.isMap())
- {
- processFailure("LLSD response for inventory item not a map", response);
- return;
- }
-
start_new_inventory_observer();
#if 0
@@ -4083,7 +4087,7 @@ void LLInventoryModel::FetchItemHttpHandler::processData(LLSD & content, LLCore:
{
changes |= gInventory.updateItem(*it);
}
- // *HUH: Have computed changes, nothing uses it.
+ // *HUH: Have computed 'changes', nothing uses it.
gInventory.notifyObservers();
gViewerWindow->getWindow()->decBusyCount();
@@ -4092,13 +4096,23 @@ void LLInventoryModel::FetchItemHttpHandler::processData(LLSD & content, LLCore:
void LLInventoryModel::FetchItemHttpHandler::processFailure(LLCore::HttpStatus status, LLCore::HttpResponse * response)
{
- LL_WARNS(LOG_INV) << dumpResponse() << LL_ENDL;
+ const std::string & ct(response->getContentType());
+ LL_WARNS(LOG_INV) << "Inventory item fetch failure\n"
+ << "[Status: " << status.toTerseString() << "]\n"
+ << "[Reason: " << status.toString() << "]\n"
+ << "[Content-type: " << ct << "]\n"
+ << "[Content (abridged): "
+ << LLCoreHttpUtil::responseToString(response) << "]" << LL_ENDL;
gInventory.notifyObservers();
}
void LLInventoryModel::FetchItemHttpHandler::processFailure(const char * const reason, LLCore::HttpResponse * response)
{
- LL_WARNS(LOG_INV) << dumpResponse() << LL_ENDL;
+ LL_WARNS(LOG_INV) << "Inventory item fetch failure\n"
+ << "[Status: internal error]\n"
+ << "[Reason: " << reason << "]\n"
+ << "[Content (abridged): "
+ << LLCoreHttpUtil::responseToString(response) << "]" << LL_ENDL;
gInventory.notifyObservers();
}
diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp
index 7b944edf45..0c04a9c039 100755
--- a/indra/newview/llinventorymodelbackgroundfetch.cpp
+++ b/indra/newview/llinventorymodelbackgroundfetch.cpp
@@ -40,17 +40,24 @@
#include "llhttpconstants.h"
#include "bufferarray.h"
#include "bufferstream.h"
-#include "llsdserialize.h"
+#include "llcorehttputil.h"
namespace
{
+//
// Http request handler class for single inventory item requests.
//
// We'll use a handler-per-request pattern here rather than
// a shared handler. Mainly convenient as this was converted
// from a Responder class model.
//
+// Derives from and is identical to the normal FetchItemHttpHandler
+// except that: 1) it uses the background request object which is
+// updated more slowly than the foreground and 2) keeps a count of
+// active requests on the LLInventoryModelBackgroundFetch object
+// to indicate outstanding operations are in-flight.
+//
class BGItemHttpHandler : public LLInventoryModel::FetchItemHttpHandler
{
LOG_CLASS(BGItemHttpHandler);
@@ -74,6 +81,10 @@ protected:
// Http request handler class for folders.
+//
+// Handler for FetchInventoryDescendents2 and FetchLibDescendents2
+// caps requests for folders.
+//
class BGFolderHttpHandler : public LLCore::HttpHandler
{
LOG_CLASS(BGFolderHttpHandler);
@@ -116,12 +127,6 @@ const S32 MAX_FETCH_RETRIES = 10;
const char * const LOG_INV("Inventory");
-std::string dumpResponse()
-{
- return std::string("ADD SOMETHING MEANINGFUL HERE");
-}
-
-
} // end of namespace anonymous
@@ -471,6 +476,10 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
return;
}
+ // *TODO: These values could be tweaked at runtime to effect
+ // a fast/slow fetch throttle. Once login is complete and the scene
+ // is mostly loaded, we could turn up the throttle and fill missing
+ // inventory more quickly.
static const S32 max_concurrent_fetches(12); // Outstanding requests, not connections
static const F32 new_min_time(0.5f); // *HACK: Clean this up when old code goes away entirely.
static const U32 max_batch_size(10);
@@ -482,7 +491,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
if (mFetchCount)
{
- // Process completed HTTP requests
+ // Process completed background HTTP requests
gInventory.handleResponses(false);
}
@@ -497,6 +506,8 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
const U32 sort_order(gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER) & 0x1);
+ // *TODO: Think I'd like to get a shared pointer to this and share it
+ // among all the folder requests.
uuid_vec_t recursive_cats;
LLSD folder_request_body;
@@ -673,7 +684,9 @@ bool LLInventoryModelBackgroundFetch::fetchQueueContainsNoDescendentsOf(const LL
}
+// ===============================
// Anonymous Namespace Definitions
+// ===============================
namespace
{
@@ -683,30 +696,53 @@ namespace
void BGFolderHttpHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response)
{
LLCore::HttpStatus status(response->getStatus());
+ // status = LLCore::HttpStatus(404); // Dev tool to force error handling
if (! status)
{
processFailure(status, response);
}
else
{
+ // Response body should be present.
LLCore::BufferArray * body(response->getBody());
+ // body = NULL; // Dev tool to force error handling
if (! body || ! body->size())
{
LL_WARNS(LOG_INV) << "Missing data in inventory folder query." << LL_ENDL;
processFailure("HTTP response missing expected body", response);
goto only_exit;
}
-
- LLCore::BufferArrayStream bas(body);
+
+ // Could test 'Content-Type' header but probably unreliable.
+
+ // Convert response to LLSD
+ // body->write(0, "Garbage Response", 16); // Dev tool to force error handling
LLSD body_llsd;
- S32 parse_status(LLSDSerialize::fromXML(body_llsd, bas));
- if (LLSDParser::PARSE_FAILURE == parse_status)
+ if (! LLCoreHttpUtil::responseToLLSD(response, true, body_llsd))
{
// INFOS-level logging will occur on the parsed failure
processFailure("HTTP response contained malformed LLSD", response);
goto only_exit;
}
+ // Expect top-level structure to be a map
+ // body_llsd = LLSD::emptyArray(); // Dev tool to force error handling
+ if (! body_llsd.isMap())
+ {
+ processFailure("LLSD response not a map", response);
+ goto only_exit;
+ }
+
+ // Check for 200-with-error failures
+ // body_llsd["error"] = LLSD::emptyMap(); // Dev tool to force error handling
+ // body_llsd["error"]["identifier"] = "Development";
+ // body_llsd["error"]["message"] = "You left development code in the viewer";
+ if (body_llsd.has("error"))
+ {
+ processFailure("Inventory application error (200-with-error)", response);
+ goto only_exit;
+ }
+
// Okay, process data if possible
processData(body_llsd, response);
}
@@ -719,13 +755,12 @@ only_exit:
void BGFolderHttpHandler::processData(LLSD & content, LLCore::HttpResponse * response)
{
- if (! content.isMap())
- {
- processFailure("LLSD response not a map", response);
- return;
- }
-
LLInventoryModelBackgroundFetch * fetcher(LLInventoryModelBackgroundFetch::getInstance());
+
+ // API V2 and earlier should probably be testing for "error" map
+ // in response as an application-level error.
+
+ // Instead, we assume success and attempt to extract information.
if (content.has("folders"))
{
LLSD folders(content["folders"]);
@@ -836,7 +871,7 @@ void BGFolderHttpHandler::processData(LLSD & content, LLCore::HttpResponse * res
folder_it != bad_folders.endArray();
++folder_it)
{
- // *TODO: Stop copying data
+ // *TODO: Stop copying data [ed: this isn't copying data]
LLSD folder_sd(*folder_it);
// These folders failed on the dataserver. We probably don't want to retry them.
@@ -857,14 +892,26 @@ void BGFolderHttpHandler::processData(LLSD & content, LLCore::HttpResponse * res
void BGFolderHttpHandler::processFailure(LLCore::HttpStatus status, LLCore::HttpResponse * response)
{
- LL_WARNS(LOG_INV) << dumpResponse() << LL_ENDL;
+ const std::string & ct(response->getContentType());
+ LL_WARNS(LOG_INV) << "Inventory folder fetch failure\n"
+ << "[Status: " << status.toTerseString() << "]\n"
+ << "[Reason: " << status.toString() << "]\n"
+ << "[Content-type: " << ct << "]\n"
+ << "[Content (abridged): "
+ << LLCoreHttpUtil::responseToString(response) << "]" << LL_ENDL;
+
+ // Could use a 404 test here to try to detect revoked caps...
+
+ // This was originally the request retry logic for the inventory
+ // request which tested on HTTP_INTERNAL_ERROR status. This
+ // retry logic was unbounded and lacked discrimination as to the
+ // cause of the retry. The new http library should be doing
+ // adquately on retries but I want to keep the structure of a
+ // retry for reference.
LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance();
-
- LL_INFOS(LOG_INV) << dumpResponse() << LL_ENDL;
-
- // *FIX: Not the correct test here...
- if (status == LLCore::HttpStatus(408)) // timed out or curl failure
+ if (false)
{
+ // timed out or curl failure
for (LLSD::array_const_iterator folder_it = mRequestSD["folders"].beginArray();
folder_it != mRequestSD["folders"].endArray();
++folder_it)
@@ -888,12 +935,20 @@ void BGFolderHttpHandler::processFailure(LLCore::HttpStatus status, LLCore::Http
void BGFolderHttpHandler::processFailure(const char * const reason, LLCore::HttpResponse * response)
{
- LL_WARNS(LOG_INV) << dumpResponse() << LL_ENDL;
+ LL_WARNS(LOG_INV) << "Inventory folder fetch failure\n"
+ << "[Status: internal error]\n"
+ << "[Reason: " << reason << "]\n"
+ << "[Content (abridged): "
+ << LLCoreHttpUtil::responseToString(response) << "]" << LL_ENDL;
+
+ // Reverse of previous processFailure() method, this is invoked
+ // when response structure is found to be invalid. Original
+ // always re-issued the request (without limit). This does
+ // the same but be aware that this may be a source of problems.
+ // Philosophy is that inventory folders are so essential to
+ // operation that this is a reasonable action.
LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance();
-
- LL_INFOS(LOG_INV) << dumpResponse() << LL_ENDL;
-
- if (true /* status == LLCore::HttpStatus(408)*/) // timed out or curl failure
+ if (true)
{
for (LLSD::array_const_iterator folder_it = mRequestSD["folders"].beginArray();
folder_it != mRequestSD["folders"].endArray();