From 74c8b028d42a8c5b080bb861e427f38cedd4ad7c Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk Date: Fri, 15 Dec 2023 18:26:14 +0100 Subject: SL-20743 Use LLMutex in LLImageBase for internal data thread-safety --- indra/newview/llwebprofile.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'indra/newview/llwebprofile.cpp') diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp index f2d7e4585a..ade9bbd847 100644 --- a/indra/newview/llwebprofile.cpp +++ b/indra/newview/llwebprofile.cpp @@ -239,10 +239,12 @@ LLCore::BufferArray::ptr_t LLWebProfile::buildPostData(const LLSD &data, LLPoint << "Content-Disposition: form-data; name=\"file\"; filename=\"snapshot.png\"\r\n" << "Content-Type: image/png\r\n\r\n"; + LLImageDataSharedLock lock(image); + // Insert the image data. //char *datap = (char *)(image->getData()); //bas.write(datap, image->getDataSize()); - U8* image_data = image->getData(); + const U8* image_data = image->getData(); for (S32 i = 0; i < image->getDataSize(); ++i) { bas << image_data[i]; -- cgit v1.2.3 From 17e1f3692c5c1e9cbc6ba6895b312a8baae9aec2 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Fri, 5 Apr 2024 19:03:58 -0400 Subject: Port from JsonCPP to Boost.Json for json parsing and serializing (#1054) --- indra/newview/llwebprofile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llwebprofile.cpp') diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp index ade9bbd847..45388becc7 100644 --- a/indra/newview/llwebprofile.cpp +++ b/indra/newview/llwebprofile.cpp @@ -42,7 +42,7 @@ #include "llcorehttputil.h" // third-party -#include "json/reader.h" // JSON + /* * Workflow: -- cgit v1.2.3 From e2e37cced861b98de8c1a7c9c0d3a50d2d90e433 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Wed, 22 May 2024 21:25:21 +0200 Subject: Fix line endlings --- indra/newview/llwebprofile.cpp | 544 ++++++++++++++++++++--------------------- 1 file changed, 272 insertions(+), 272 deletions(-) (limited to 'indra/newview/llwebprofile.cpp') diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp index 8559f6275b..83e417633a 100644 --- a/indra/newview/llwebprofile.cpp +++ b/indra/newview/llwebprofile.cpp @@ -1,272 +1,272 @@ -/** - * @file llwebprofile.cpp - * @brief Web profile access. - * - * $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 "llwebprofile.h" - -// libs -#include "llbufferstream.h" -#include "llimagepng.h" - -#include "llsdserialize.h" -#include "llstring.h" - -// newview -#include "llavataractions.h" // for getProfileURL() -#include "llviewermedia.h" // FIXME: don't use LLViewerMedia internals - -#include "llcorehttputil.h" - -// third-party - - -/* - * Workflow: - * 1. LLViewerMedia::setOpenIDCookie() - * -> GET https://my-demo.secondlife.com/ via LLViewerMediaWebProfileResponder - * -> LLWebProfile::setAuthCookie() - * 2. LLWebProfile::uploadImage() - * -> GET "https://my-demo.secondlife.com/snapshots/s3_upload_config" via ConfigResponder - * 3. LLWebProfile::post() - * -> POST via PostImageResponder - * -> redirect - * -> GET via PostImageRedirectResponder - */ - -/////////////////////////////////////////////////////////////////////////////// -// LLWebProfile - -std::string LLWebProfile::sAuthCookie; -LLWebProfile::status_callback_t LLWebProfile::mStatusCallback; - -// static -void LLWebProfile::uploadImage(LLPointer image, const std::string& caption, bool add_location) -{ - LLCoros::instance().launch("LLWebProfile::uploadImageCoro", - boost::bind(&LLWebProfile::uploadImageCoro, image, caption, add_location)); - -} - -// static -void LLWebProfile::setAuthCookie(const std::string& cookie) -{ - LL_DEBUGS("Snapshots") << "Setting auth cookie: " << cookie << LL_ENDL; - sAuthCookie = cookie; -} - - -/*static*/ -LLCore::HttpHeaders::ptr_t LLWebProfile::buildDefaultHeaders() -{ - LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders); - LLSD headers = LLViewerMedia::getInstance()->getHeaders(); - - for (LLSD::map_iterator it = headers.beginMap(); it != headers.endMap(); ++it) - { - httpHeaders->append((*it).first, (*it).second.asStringRef()); - } - - return httpHeaders; -} - - -/*static*/ -void LLWebProfile::uploadImageCoro(LLPointer 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; - - if (dynamic_cast(image.get()) == 0) - { - LL_WARNS() << "Image to upload is not a PNG" << LL_ENDL; - llassert(dynamic_cast(image.get()) != 0); - return; - } - - httpOpts->setWantHeaders(true); - httpOpts->setFollowRedirects(false); - httpOpts->setSSLVerifyPeer(false); ; // viewer's cert bundle doesn't appear to agree with web certs from "https://my.secondlife.com/" - - // 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"); - - LL_DEBUGS("Snapshots") << "Requesting " << configUrl << LL_ENDL; - - httpHeaders = buildDefaultHeaders(); - httpHeaders->append(HTTP_OUT_HEADER_COOKIE, getAuthCookie()); - - LLSD result = httpAdapter->getJsonAndSuspend(httpRequest, configUrl, httpOpts, httpHeaders); - - LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - - 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->postAndSuspend(httpRequest, uploadUrl, body, httpOpts, httpHeaders); - - body.reset(); - httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - - if (!status && (status != LLCore::HttpStatus(HTTP_SEE_OTHER))) - { - LL_WARNS("Snapshots") << "Failed to upload image data." << LL_ENDL; - LLWebProfile::reportImageUploadStatus(false); - return; - } - - LLSD resultHeaders = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_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->getRawAndSuspend(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 &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"; - - LLImageDataSharedLock lock(image); - - // Insert the image data. - //char *datap = (char *)(image->getData()); - //bas.write(datap, image->getDataSize()); - const 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 -void LLWebProfile::reportImageUploadStatus(bool ok) -{ - if (mStatusCallback) - { - mStatusCallback(ok); - } -} - -// static -std::string LLWebProfile::getAuthCookie() -{ - // This is needed to test image uploads on Linux viewer built with OpenSSL 1.0.0 (0.9.8 works fine). - return LLStringUtil::getenv("LL_SNAPSHOT_COOKIE", sAuthCookie); -} +/** + * @file llwebprofile.cpp + * @brief Web profile access. + * + * $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 "llwebprofile.h" + +// libs +#include "llbufferstream.h" +#include "llimagepng.h" + +#include "llsdserialize.h" +#include "llstring.h" + +// newview +#include "llavataractions.h" // for getProfileURL() +#include "llviewermedia.h" // FIXME: don't use LLViewerMedia internals + +#include "llcorehttputil.h" + +// third-party + + +/* + * Workflow: + * 1. LLViewerMedia::setOpenIDCookie() + * -> GET https://my-demo.secondlife.com/ via LLViewerMediaWebProfileResponder + * -> LLWebProfile::setAuthCookie() + * 2. LLWebProfile::uploadImage() + * -> GET "https://my-demo.secondlife.com/snapshots/s3_upload_config" via ConfigResponder + * 3. LLWebProfile::post() + * -> POST via PostImageResponder + * -> redirect + * -> GET via PostImageRedirectResponder + */ + +/////////////////////////////////////////////////////////////////////////////// +// LLWebProfile + +std::string LLWebProfile::sAuthCookie; +LLWebProfile::status_callback_t LLWebProfile::mStatusCallback; + +// static +void LLWebProfile::uploadImage(LLPointer image, const std::string& caption, bool add_location) +{ + LLCoros::instance().launch("LLWebProfile::uploadImageCoro", + boost::bind(&LLWebProfile::uploadImageCoro, image, caption, add_location)); + +} + +// static +void LLWebProfile::setAuthCookie(const std::string& cookie) +{ + LL_DEBUGS("Snapshots") << "Setting auth cookie: " << cookie << LL_ENDL; + sAuthCookie = cookie; +} + + +/*static*/ +LLCore::HttpHeaders::ptr_t LLWebProfile::buildDefaultHeaders() +{ + LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders); + LLSD headers = LLViewerMedia::getInstance()->getHeaders(); + + for (LLSD::map_iterator it = headers.beginMap(); it != headers.endMap(); ++it) + { + httpHeaders->append((*it).first, (*it).second.asStringRef()); + } + + return httpHeaders; +} + + +/*static*/ +void LLWebProfile::uploadImageCoro(LLPointer 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; + + if (dynamic_cast(image.get()) == 0) + { + LL_WARNS() << "Image to upload is not a PNG" << LL_ENDL; + llassert(dynamic_cast(image.get()) != 0); + return; + } + + httpOpts->setWantHeaders(true); + httpOpts->setFollowRedirects(false); + httpOpts->setSSLVerifyPeer(false); ; // viewer's cert bundle doesn't appear to agree with web certs from "https://my.secondlife.com/" + + // 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"); + + LL_DEBUGS("Snapshots") << "Requesting " << configUrl << LL_ENDL; + + httpHeaders = buildDefaultHeaders(); + httpHeaders->append(HTTP_OUT_HEADER_COOKIE, getAuthCookie()); + + LLSD result = httpAdapter->getJsonAndSuspend(httpRequest, configUrl, httpOpts, httpHeaders); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + 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->postAndSuspend(httpRequest, uploadUrl, body, httpOpts, httpHeaders); + + body.reset(); + httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status && (status != LLCore::HttpStatus(HTTP_SEE_OTHER))) + { + LL_WARNS("Snapshots") << "Failed to upload image data." << LL_ENDL; + LLWebProfile::reportImageUploadStatus(false); + return; + } + + LLSD resultHeaders = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_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->getRawAndSuspend(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 &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"; + + LLImageDataSharedLock lock(image); + + // Insert the image data. + //char *datap = (char *)(image->getData()); + //bas.write(datap, image->getDataSize()); + const 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 +void LLWebProfile::reportImageUploadStatus(bool ok) +{ + if (mStatusCallback) + { + mStatusCallback(ok); + } +} + +// static +std::string LLWebProfile::getAuthCookie() +{ + // This is needed to test image uploads on Linux viewer built with OpenSSL 1.0.0 (0.9.8 works fine). + return LLStringUtil::getenv("LL_SNAPSHOT_COOKIE", sAuthCookie); +} -- cgit v1.2.3