summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2026-07-01 22:53:16 +0300
committerAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2026-07-03 16:15:04 +0300
commitf2c356fc7130ce5e38b994dcfa1e210609b458b9 (patch)
treea93da65897eaea9c09b4c3f2c1d07b3de8a0d861 /indra/newview
parentc99cd251383ed17b4dd1210ee0701d2a3b4dd0e5 (diff)
#4094 Handle two stage uploads more reliably
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llfloatersimplesnapshot.cpp197
-rw-r--r--indra/newview/llpanelprofile.cpp158
-rw-r--r--indra/newview/llviewerassetupload.cpp95
3 files changed, 303 insertions, 147 deletions
diff --git a/indra/newview/llfloatersimplesnapshot.cpp b/indra/newview/llfloatersimplesnapshot.cpp
index 55b39d9193..4671f74d6d 100644
--- a/indra/newview/llfloatersimplesnapshot.cpp
+++ b/indra/newview/llfloatersimplesnapshot.cpp
@@ -54,87 +54,162 @@ void post_thumbnail_image_coro(std::string cap_url, std::string path_to_image, L
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter = std::make_shared<LLCoreHttpUtil::HttpCoroutineAdapter>("post_profile_image_coro", httpPolicy);
+ httpAdapter = std::make_shared<LLCoreHttpUtil::HttpCoroutineAdapter>("post_thumbnail_image_coro", httpPolicy);
LLCore::HttpRequest::ptr_t httpRequest = std::make_shared<LLCore::HttpRequest>();
LLCore::HttpHeaders::ptr_t httpHeaders;
LLCore::HttpOptions::ptr_t httpOpts = std::make_shared<LLCore::HttpOptions>();
httpOpts->setFollowRedirects(true);
- LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, first_data, httpOpts, httpHeaders);
+ // Retry stage-2 upload by re-requesting a fresh one-time uploader capability (up to 3 attempts total)
+ const S32 MAX_UPLOAD_RETRIES = 2;
+ S32 upload_retry_count = 0;
+ LLUUID result_uuid;
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (!status)
- {
- // todo: notification?
- LL_WARNS("AvatarProperties") << "Failed to get uploader cap " << status.toString() << LL_ENDL;
- return;
- }
- if (!result.has("uploader"))
+ while (upload_retry_count <= MAX_UPLOAD_RETRIES)
{
- // todo: notification?
- LL_WARNS("AvatarProperties") << "Failed to get uploader cap, response contains no data." << LL_ENDL;
- return;
- }
- std::string uploader_cap = result["uploader"].asString();
- if (uploader_cap.empty())
- {
- LL_WARNS("AvatarProperties") << "Failed to get uploader cap, cap invalid." << LL_ENDL;
- return;
- }
+ // Stage 1: Request uploader URL
+ LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, first_data, httpOpts, httpHeaders);
- // Upload the image
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
- LLCore::HttpRequest::ptr_t uploaderhttpRequest = std::make_shared<LLCore::HttpRequest>();
- LLCore::HttpHeaders::ptr_t uploaderhttpHeaders = std::make_shared<LLCore::HttpHeaders>();
- LLCore::HttpOptions::ptr_t uploaderhttpOpts = std::make_shared<LLCore::HttpOptions>();
- S64 length;
+ if (!status)
+ {
+ LL_WARNS("Thumbnail") << "Failed to get uploader cap " << status.toString() << LL_ENDL;
+ if (callback)
+ {
+ callback(LLUUID());
+ }
+ LLFile::remove(path_to_image);
+ return;
+ }
- {
- llifstream instream(path_to_image.c_str(), std::iostream::binary | std::iostream::ate);
- if (!instream.is_open())
+ if (!result.has("uploader"))
{
- LL_WARNS("AvatarProperties") << "Failed to open file " << path_to_image << LL_ENDL;
+ LL_WARNS("Thumbnail") << "Failed to get uploader cap, response contains no data." << LL_ENDL;
+ if (callback)
+ {
+ callback(LLUUID());
+ }
+ LLFile::remove(path_to_image);
return;
}
- length = instream.tellg();
- }
- uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/jp2"); // optional
- uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_LENGTH, llformat("%d", length)); // required!
- uploaderhttpOpts->setFollowRedirects(true);
+ std::string uploader_cap = result["uploader"].asString();
+ if (uploader_cap.empty())
+ {
+ LL_WARNS("Thumbnail") << "Failed to get uploader cap, cap invalid." << LL_ENDL;
+ if (callback)
+ {
+ callback(LLUUID());
+ }
+ LLFile::remove(path_to_image);
+ return;
+ }
- result = httpAdapter->postFileAndSuspend(uploaderhttpRequest, uploader_cap, path_to_image, uploaderhttpOpts, uploaderhttpHeaders);
+ // Stage 2: Upload the image
+ LLCore::HttpRequest::ptr_t uploaderhttpRequest = std::make_shared<LLCore::HttpRequest>();
+ LLCore::HttpHeaders::ptr_t uploaderhttpHeaders = std::make_shared<LLCore::HttpHeaders>();
+ LLCore::HttpOptions::ptr_t uploaderhttpOpts = std::make_shared<LLCore::HttpOptions>();
+ S64 length;
- httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+ {
+ llifstream instream(path_to_image.c_str(), std::iostream::binary | std::iostream::ate);
+ if (!instream.is_open())
+ {
+ LL_WARNS("Thumbnail") << "Failed to open file " << path_to_image << LL_ENDL;
+ if (callback)
+ {
+ callback(LLUUID());
+ }
+ LLFile::remove(path_to_image);
+ return;
+ }
+ length = instream.tellg();
+ }
- LL_DEBUGS("Thumbnail") << result << LL_ENDL;
+ uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/jp2");
+ uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_LENGTH, std::to_string(length));
+ uploaderhttpOpts->setFollowRedirects(true);
- if (!status)
- {
- LL_WARNS("Thumbnail") << "Failed to upload image " << status.toString() << LL_ENDL;
- return;
- }
+ result = httpAdapter->postFileAndSuspend(uploaderhttpRequest, uploader_cap, path_to_image, uploaderhttpOpts, uploaderhttpHeaders);
- if (result["state"].asString() != "complete")
- {
- if (result.has("message"))
- {
- LL_WARNS("Thumbnail") << "Failed to upload image, state " << result["state"] << " message: " << result["message"] << LL_ENDL;
- }
- else
+ httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ LL_DEBUGS("Thumbnail") << result << LL_ENDL;
+
+ if (!status)
{
- LL_WARNS("Thumbnail") << "Failed to upload image " << result << LL_ENDL;
+ if (upload_retry_count < MAX_UPLOAD_RETRIES)
+ {
+ upload_retry_count++;
+ LL_WARNS("Thumbnail") << "Failed to upload image (attempt " << upload_retry_count
+ << " of " << (MAX_UPLOAD_RETRIES + 1) << "): " << status.toString()
+ << ", re-requesting uploader..." << LL_ENDL;
+ llcoro::suspendUntilTimeout(1.0f);
+ continue;
+ }
+ else
+ {
+ LL_WARNS("Thumbnail") << "Failed to upload image after " << (MAX_UPLOAD_RETRIES + 1)
+ << " attempts: " << status.toString() << LL_ENDL;
+ if (callback)
+ {
+ callback(LLUUID());
+ }
+ LLFile::remove(path_to_image);
+ return;
+ }
}
- if (callback)
+ if (result["state"].asString() != "complete")
{
- callback(LLUUID());
+ if (upload_retry_count < MAX_UPLOAD_RETRIES)
+ {
+ upload_retry_count++;
+ if (result.has("message"))
+ {
+ LL_WARNS("Thumbnail") << "Failed to upload image, state " << result["state"]
+ << " message: " << result["message"] << " (attempt "
+ << upload_retry_count << " of " << (MAX_UPLOAD_RETRIES + 1)
+ << "), re-requesting uploader..." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("Thumbnail") << "Failed to upload image (attempt " << upload_retry_count
+ << " of " << (MAX_UPLOAD_RETRIES + 1)
+ << "), re-requesting uploader..." << LL_ENDL;
+ }
+ llcoro::suspendUntilTimeout(1.0f);
+ continue;
+ }
+ else
+ {
+ if (result.has("message"))
+ {
+ LL_WARNS("Thumbnail") << "Failed to upload image after " << (MAX_UPLOAD_RETRIES + 1)
+ << " attempts, state " << result["state"]
+ << " message: " << result["message"] << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("Thumbnail") << "Failed to upload image after " << (MAX_UPLOAD_RETRIES + 1)
+ << " attempts" << LL_ENDL;
+ }
+ if (callback)
+ {
+ callback(LLUUID());
+ }
+ LLFile::remove(path_to_image);
+ return;
+ }
}
- return;
+
+ // Success!
+ result_uuid = result["new_asset"].asUUID();
+ break;
}
if (first_data.has("category_id"))
@@ -143,7 +218,7 @@ void post_thumbnail_image_coro(std::string cap_url, std::string path_to_image, L
LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
if (cat)
{
- cat->setThumbnailUUID(result["new_asset"].asUUID());
+ cat->setThumbnailUUID(result_uuid);
}
gInventory.addChangedMask(LLInventoryObserver::INTERNAL, cat_id);
}
@@ -153,16 +228,18 @@ void post_thumbnail_image_coro(std::string cap_url, std::string path_to_image, L
LLViewerInventoryItem* item = gInventory.getItem(item_id);
if (item)
{
- item->setThumbnailUUID(result["new_asset"].asUUID());
+ item->setThumbnailUUID(result_uuid);
}
- // Are we supposed to get BulkUpdateInventory?
gInventory.addChangedMask(LLInventoryObserver::INTERNAL, item_id);
}
if (callback)
{
- callback(result["new_asset"].asUUID());
+ callback(result_uuid);
}
+
+ // Cleanup
+ LLFile::remove(path_to_image);
}
///----------------------------------------------------------------------------
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index 34d2d4d6a5..b33696244d 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -113,77 +113,131 @@ LLUUID post_profile_image(std::string cap_url, const LLSD &first_data, std::stri
LLCore::HttpOptions::ptr_t httpOpts = std::make_shared<LLCore::HttpOptions>();
httpOpts->setFollowRedirects(true);
- LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, first_data, httpOpts, httpHeaders);
+ // Retry stage-2 upload by re-requesting a fresh one-time uploader capability (up to 3 attempts total)
+ const S32 MAX_UPLOAD_RETRIES = 2;
+ S32 upload_retry_count = 0;
+ LLUUID result_uuid;
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (!status)
- {
- // todo: notification?
- LL_WARNS("AvatarProperties") << "Failed to get uploader cap " << status.toString() << LL_ENDL;
- return LLUUID::null;
- }
- if (!result.has("uploader"))
+ while (upload_retry_count <= MAX_UPLOAD_RETRIES)
{
- // todo: notification?
- LL_WARNS("AvatarProperties") << "Failed to get uploader cap, response contains no data." << LL_ENDL;
- return LLUUID::null;
- }
- std::string uploader_cap = result["uploader"].asString();
- if (uploader_cap.empty())
- {
- LL_WARNS("AvatarProperties") << "Failed to get uploader cap, cap invalid." << LL_ENDL;
- return LLUUID::null;
- }
+ // Stage 1: Request uploader URL
+ LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, first_data, httpOpts, httpHeaders);
- // Upload the image
- LLCore::HttpRequest::ptr_t uploaderhttpRequest = std::make_shared<LLCore::HttpRequest>();
- LLCore::HttpHeaders::ptr_t uploaderhttpHeaders = std::make_shared<LLCore::HttpHeaders>();
- LLCore::HttpOptions::ptr_t uploaderhttpOpts = std::make_shared<LLCore::HttpOptions>();
- S64 length;
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
- {
- llifstream instream(path_to_image.c_str(), std::iostream::binary | std::iostream::ate);
- if (!instream.is_open())
+ if (!status)
{
- LL_WARNS("AvatarProperties") << "Failed to open file " << path_to_image << LL_ENDL;
+ // todo: notification?
+ LL_WARNS("AvatarProperties") << "Failed to get uploader cap " << status.toString() << LL_ENDL;
+ return LLUUID::null;
+ }
+
+ if (!result.has("uploader"))
+ {
+ // todo: notification?
+ LL_WARNS("AvatarProperties") << "Failed to get uploader cap, response contains no data." << LL_ENDL;
return LLUUID::null;
}
- length = instream.tellg();
- }
- uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/jp2"); // optional
- uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_LENGTH, llformat("%d", length)); // required!
- uploaderhttpOpts->setFollowRedirects(true);
+ std::string uploader_cap = result["uploader"].asString();
+ if (uploader_cap.empty())
+ {
+ LL_WARNS("AvatarProperties") << "Failed to get uploader cap, cap invalid." << LL_ENDL;
+ return LLUUID::null;
+ }
+
+ // Stage 2: Upload the image
+ LLCore::HttpRequest::ptr_t uploaderhttpRequest = std::make_shared<LLCore::HttpRequest>();
+ LLCore::HttpHeaders::ptr_t uploaderhttpHeaders = std::make_shared<LLCore::HttpHeaders>();
+ LLCore::HttpOptions::ptr_t uploaderhttpOpts = std::make_shared<LLCore::HttpOptions>();
+ S64 length;
+
+ {
+ llifstream instream(path_to_image.c_str(), std::iostream::binary | std::iostream::ate);
+ if (!instream.is_open())
+ {
+ LL_WARNS("AvatarProperties") << "Failed to open file " << path_to_image << LL_ENDL;
+ return LLUUID::null;
+ }
+ length = instream.tellg();
+ }
- result = httpAdapter->postFileAndSuspend(uploaderhttpRequest, uploader_cap, path_to_image, uploaderhttpOpts, uploaderhttpHeaders);
+ uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/jp2");
+ uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_LENGTH, std::to_string(length));
+ uploaderhttpOpts->setFollowRedirects(true);
- httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+ result = httpAdapter->postFileAndSuspend(uploaderhttpRequest, uploader_cap, path_to_image, uploaderhttpOpts, uploaderhttpHeaders);
- LL_DEBUGS("AvatarProperties") << result << LL_ENDL;
+ httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
- if (!status)
- {
- LL_WARNS("AvatarProperties") << "Failed to upload image " << status.toString() << LL_ENDL;
- return LLUUID::null;
- }
+ LL_DEBUGS("AvatarProperties") << result << LL_ENDL;
- if (result["state"].asString() != "complete")
- {
- if (result.has("message"))
+ if (!status)
{
- LL_WARNS("AvatarProperties") << "Failed to upload image, state " << result["state"] << " message: " << result["message"] << LL_ENDL;
+ if (upload_retry_count < MAX_UPLOAD_RETRIES)
+ {
+ upload_retry_count++;
+ LL_WARNS("AvatarProperties") << "Failed to upload image (attempt " << upload_retry_count
+ << " of " << (MAX_UPLOAD_RETRIES + 1) << "): " << status.toString()
+ << ", re-requesting uploader..." << LL_ENDL;
+ llcoro::suspendUntilTimeout(1.0f);
+ continue;
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to upload image after " << (MAX_UPLOAD_RETRIES + 1)
+ << " attempts: " << status.toString() << LL_ENDL;
+ return LLUUID::null;
+ }
}
- else
+
+ // Todo: should we really repeat if 'complete' not set?
+ if (result["state"].asString() != "complete")
{
- LL_WARNS("AvatarProperties") << "Failed to upload image " << result << LL_ENDL;
+ if (upload_retry_count < MAX_UPLOAD_RETRIES)
+ {
+ upload_retry_count++;
+ if (result.has("message"))
+ {
+ LL_WARNS("AvatarProperties") << "Failed to upload image, state " << result["state"]
+ << " message: " << result["message"] << " (attempt "
+ << upload_retry_count << " of " << (MAX_UPLOAD_RETRIES + 1)
+ << "), re-requesting uploader..." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to upload image (attempt " << upload_retry_count
+ << " of " << (MAX_UPLOAD_RETRIES + 1)
+ << "), re-requesting uploader..." << LL_ENDL;
+ }
+ llcoro::suspendUntilTimeout(1.0f);
+ continue;
+ }
+ else
+ {
+ if (result.has("message"))
+ {
+ LL_WARNS("AvatarProperties") << "Failed to upload image after " << (MAX_UPLOAD_RETRIES + 1)
+ << " attempts, state " << result["state"]
+ << " message: " << result["message"] << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to upload image after " << (MAX_UPLOAD_RETRIES + 1)
+ << " attempts" << LL_ENDL;
+ }
+ return LLUUID::null;
+ }
}
- return LLUUID::null;
+
+ // Success!
+ result_uuid = result["new_asset"].asUUID();
+ break;
}
- return result["new_asset"].asUUID();
+ return result_uuid;
}
enum EProfileImageType
diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp
index 65a69acc88..46c76e2953 100644
--- a/indra/newview/llviewerassetupload.cpp
+++ b/indra/newview/llviewerassetupload.cpp
@@ -881,6 +881,7 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti
if (uploadInfo->showUploadDialog())
{
+ // todo: localize this string
std::string uploadMessage = "Uploading...\n\n";
uploadMessage.append(uploadInfo->getDisplayName());
LLUploadDialog::modalUploadDialog(uploadMessage);
@@ -888,66 +889,90 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti
LLSD body = uploadInfo->generatePostBody();
- result = httpAdapter->postAndSuspend(httpRequest, url, body, httpOptions);
+ // Retry stage-2 upload by re-requesting a fresh one-time uploader capability (up to 3 attempts total)
+ const S32 MAX_UPLOAD_RETRIES = 2;
+ S32 upload_retry_count = 0;
+ LLCore::HttpStatus status;
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if ((!status) || (result.has("error")))
+ while (upload_retry_count <= MAX_UPLOAD_RETRIES)
{
- HandleUploadError(status, result, uploadInfo);
- if (uploadInfo->showUploadDialog())
- LLUploadDialog::modalUploadFinished();
- return;
- }
+ // Stage 1: Request uploader URL
+ result = httpAdapter->postAndSuspend(httpRequest, url, body, httpOptions);
- std::string uploader = result["uploader"].asString();
-
- bool success = false;
- if (!uploader.empty() && uploadInfo->getAssetId().notNull())
- {
- result = httpAdapter->postFileAndSuspend(httpRequest, uploader, uploadInfo->getAssetId(), uploadInfo->getAssetType(), httpOptions);
- httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
- std::string ulstate = result["state"].asString();
-
- if ((!status) || (ulstate != "complete"))
+ if ((!status) || (result.has("error")))
{
HandleUploadError(status, result, uploadInfo);
if (uploadInfo->showUploadDialog())
LLUploadDialog::modalUploadFinished();
return;
}
- if (!result.has("success"))
+
+ std::string uploader = result["uploader"].asString();
+ if (uploader.empty() || uploadInfo->getAssetId().isNull())
{
- result["success"] = LLSD::Boolean((ulstate == "complete") && status);
+ LL_WARNS() << "No upload url provided. Nothing uploaded, responding with previous result." << LL_ENDL;
+ break;
}
- S32 uploadPrice = result["upload_price"].asInteger();
+ // Stage 2: Upload to the uploader URL
+ result = httpAdapter->postFileAndSuspend(httpRequest, uploader, uploadInfo->getAssetId(), uploadInfo->getAssetType(), httpOptions);
+ httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
- if (uploadPrice > 0)
- {
- // this upload costed us L$, update our balance
- // and display something saying that it cost L$
- LLStatusBar::sendMoneyBalanceRequest();
+ std::string ulstate = result["state"].asString();
- LLSD args;
- args["AMOUNT"] = llformat("%d", uploadPrice);
- LLNotificationsUtil::add("UploadPayment", args);
+ if ((!status) || (ulstate != "complete"))
+ {
+ if (upload_retry_count < MAX_UPLOAD_RETRIES)
+ {
+ upload_retry_count++;
+ LL_WARNS() << "Upload to uploader failed (attempt " << upload_retry_count
+ << " of " << (MAX_UPLOAD_RETRIES + 1) << "), re-requesting uploader..." << LL_ENDL;
+ llcoro::suspendUntilTimeout(1.0f);
+ continue;
+ }
+ else
+ {
+ HandleUploadError(status, result, uploadInfo);
+ if (uploadInfo->showUploadDialog())
+ LLUploadDialog::modalUploadFinished();
+ return;
+ }
}
+
+ // Success!
+ break;
}
- else
+
+ if (!result.has("success"))
+ {
+ result["success"] = LLSD::Boolean((result["state"].asString() == "complete") && status);
+ }
+
+ S32 uploadPrice = result["upload_price"].asInteger();
+
+ if (uploadPrice > 0)
{
- LL_WARNS() << "No upload url provided. Nothing uploaded, responding with previous result." << LL_ENDL;
+ // 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);
+ bool succeeded = false;
if (uploadInfo->showInventoryPanel())
{
if (serverInventoryItem.notNull())
{
- success = true;
+ succeeded = true;
LLFocusableElement* focus = gFocusMgr.getKeyboardFocus();
@@ -973,7 +998,7 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti
LLFloater* floater_snapshot = LLFloaterReg::findInstance("snapshot");
if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_snapshot && floater_snapshot->isShown())
{
- floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", success).with("msg", "inventory")));
+ floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", succeeded).with("msg", "inventory")));
}
}