From 65e144d9fec4bb441050e73136ed95b48e6e363c Mon Sep 17 00:00:00 2001 From: Vadim ProductEngine Date: Wed, 2 Nov 2011 19:05:13 +0200 Subject: STORM-1580 WIP Initial commit for PO review. --- indra/newview/llwebprofile.cpp | 297 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 297 insertions(+) create mode 100644 indra/newview/llwebprofile.cpp (limited to 'indra/newview/llwebprofile.cpp') diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp new file mode 100644 index 0000000000..bb8a9a491b --- /dev/null +++ b/indra/newview/llwebprofile.cpp @@ -0,0 +1,297 @@ +/** + * @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 "llhttpclient.h" +#include "llplugincookiestore.h" + +// newview +#include "llpanelprofile.h" // for getProfileURL(). FIXME: move the method to LLAvatarActions +#include "llviewermedia.h" // FIXME: don't use LLViewerMedia internals + +// third-party +#include "reader.h" // JSON + +/* + * 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 + */ + +/////////////////////////////////////////////////////////////////////////////// +// LLWebProfileResponders::ConfigResponder + +class LLWebProfileResponders::ConfigResponder : public LLHTTPClient::Responder +{ + LOG_CLASS(LLWebProfileResponders::ConfigResponder); + +public: + ConfigResponder(LLPointer imagep) + : mImagep(imagep) + { + } + + /*virtual*/ void completedRaw( + U32 status, + const std::string& reason, + const LLChannelDescriptors& channels, + const LLIOPipe::buffer_ptr_t& buffer) + { + LLBufferStream istr(channels, buffer.get()); + std::stringstream strstrm; + strstrm << istr.rdbuf(); + const std::string body = strstrm.str(); + + if (status != 200) + { + llwarns << "Failed to get upload config (" << status << ")" << llendl; + LLWebProfile::reportImageUploadStatus(false); + return; + } + + Json::Value root; + Json::Reader reader; + if (!reader.parse(body, root)) + { + llwarns << "Failed to parse upload config: " << reader.getFormatedErrorMessages() << llendl; + LLWebProfile::reportImageUploadStatus(false); + return; + } + + // *TODO: 404 = not supported by the grid + // *TODO: increase timeout or handle 499 Expired + + // Convert config to LLSD. + const Json::Value data = root["data"]; + const std::string upload_url = root["url"].asString(); + LLSD config; + config["acl"] = data["acl"].asString(); + config["AWSAccessKeyId"] = data["AWSAccessKeyId"].asString(); + config["Content-Type"] = data["Content-Type"].asString(); + config["key"] = data["key"].asString(); + config["policy"] = data["policy"].asString(); + config["success_action_redirect"] = data["success_action_redirect"].asString(); + config["signature"] = data["signature"].asString(); + config["add_loc"] = data.get("add_loc", "0").asString(); + config["caption"] = data.get("caption", "").asString(); + + // Do the actual image upload using the configuration. + LL_DEBUGS("Snapshots") << "Got upload config, POSTing image to " << upload_url << ", config=[" << config << "]" << llendl; + LLWebProfile::post(mImagep, config, upload_url); + } + +private: + LLPointer mImagep; +}; + +/////////////////////////////////////////////////////////////////////////////// +// LLWebProfilePostImageRedirectResponder +class LLWebProfileResponders::PostImageRedirectResponder : public LLHTTPClient::Responder +{ + LOG_CLASS(LLWebProfileResponders::PostImageRedirectResponder); + +public: + /*virtual*/ void completedRaw( + U32 status, + const std::string& reason, + const LLChannelDescriptors& channels, + const LLIOPipe::buffer_ptr_t& buffer) + { + if (status != 200) + { + llwarns << "Failed to upload image: " << status << " " << reason << llendl; + LLWebProfile::reportImageUploadStatus(false); + return; + } + + LLBufferStream istr(channels, buffer.get()); + std::stringstream strstrm; + strstrm << istr.rdbuf(); + const std::string body = strstrm.str(); + llinfos << "Image uploaded." << llendl; + LL_DEBUGS("Snapshots") << "Uploading image succeeded. Response: [" << body << "]" << llendl; + LLWebProfile::reportImageUploadStatus(true); + } + +private: + LLPointer mImagep; +}; + + +/////////////////////////////////////////////////////////////////////////////// +// LLWebProfileResponders::PostImageResponder +class LLWebProfileResponders::PostImageResponder : public LLHTTPClient::Responder +{ + LOG_CLASS(LLWebProfileResponders::PostImageResponder); + +public: + /*virtual*/ void completedHeader(U32 status, const std::string& reason, const LLSD& content) + { + // Viewer seems to fail to follow a 303 redirect on POST request + // (URLRequest Error: 65, Send failed since rewinding of the data stream failed). + // Handle it manually. + if (status == 303) + { + LLSD headers = LLViewerMedia::getHeaders(); + headers["Cookie"] = LLWebProfile::getAuthCookie(); + const std::string& redir_url = content["location"]; + LL_DEBUGS("Snapshots") << "Got redirection URL: " << redir_url << llendl; + LLHTTPClient::get(redir_url, new LLWebProfileResponders::PostImageRedirectResponder, headers); + } + else + { + llwarns << "Unexpected POST status: " << status << " " << reason << llendl; + LL_DEBUGS("Snapshots") << "headers: [" << content << "]" << llendl; + LLWebProfile::reportImageUploadStatus(false); + } + } + + // Override just to suppress warnings. + /*virtual*/ void completedRaw(U32 status, const std::string& reason, + const LLChannelDescriptors& channels, + const LLIOPipe::buffer_ptr_t& buffer) + { + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// LLWebProfile + +std::string LLWebProfile::sAuthCookie; +LLWebProfile::status_callback_t LLWebProfile::mStatusCallback; + +// static +void LLWebProfile::uploadImage(LLPointer image, const std::string& caption, bool add_location) +{ + // Get upload configuration data. + std::string config_url(getProfileURL(LLStringUtil::null) + "snapshots/s3_upload_config"); + config_url += "?caption=" + LLURI::escape(caption); + config_url += "&add_loc=" + std::string(add_location ? "1" : "0"); + + LL_DEBUGS("Snapshots") << "Requesting " << config_url << llendl; + LLSD headers = LLViewerMedia::getHeaders(); + headers["Cookie"] = getAuthCookie(); + LLHTTPClient::get(config_url, new LLWebProfileResponders::ConfigResponder(image), headers); +} + +// static +void LLWebProfile::setAuthCookie(const std::string& cookie) +{ + LL_DEBUGS("Snapshots") << "Setting auth cookie: " << cookie << llendl; + sAuthCookie = cookie; +} + +// static +void LLWebProfile::post(LLPointer image, const LLSD& config, const std::string& url) +{ + // *TODO: make sure it's a jpeg? + + const std::string boundary = "----------------------------0123abcdefab"; + + LLSD headers = LLViewerMedia::getHeaders(); + headers["Cookie"] = getAuthCookie(); + headers["Content-Type"] = "multipart/form-data; boundary=" + boundary; + + std::ostringstream body; + + // *NOTE: The order seems to matter. + body << "--" << boundary << "\r\n" + << "Content-Disposition: form-data; name=\"key\"\r\n\r\n" + << config["key"].asString() << "\r\n"; + + body << "--" << boundary << "\r\n" + << "Content-Disposition: form-data; name=\"AWSAccessKeyId\"\r\n\r\n" + << config["AWSAccessKeyId"].asString() << "\r\n"; + + body << "--" << boundary << "\r\n" + << "Content-Disposition: form-data; name=\"acl\"\r\n\r\n" + << config["acl"].asString() << "\r\n"; + + body << "--" << boundary << "\r\n" + << "Content-Disposition: form-data; name=\"Content-Type\"\r\n\r\n" + << config["Content-Type"].asString() << "\r\n"; + + body << "--" << boundary << "\r\n" + << "Content-Disposition: form-data; name=\"policy\"\r\n\r\n" + << config["policy"].asString() << "\r\n"; + + body << "--" << boundary << "\r\n" + << "Content-Disposition: form-data; name=\"signature\"\r\n\r\n" + << config["signature"].asString() << "\r\n"; + + body << "--" << boundary << "\r\n" + << "Content-Disposition: form-data; name=\"success_action_redirect\"\r\n\r\n" + << config["success_action_redirect"].asString() << "\r\n"; + + body << "--" << boundary << "\r\n" + << "Content-Disposition: form-data; name=\"file\"; filename=\"snapshot.jpg\"\r\n" + << "Content-Type: image/jpeg\r\n\r\n"; + + // Insert the image data. + // *FIX: Treating this as a string will probably screw it up ... + U8* image_data = image->getData(); + for (S32 i = 0; i < image->getDataSize(); ++i) + { + body << image_data[i]; + } + + body << "\r\n--" << boundary << "--\r\n"; + + // postRaw() takes ownership of the buffer and releases it later. + size_t size = body.str().size(); + U8 *data = new U8[size]; + memcpy(data, body.str().data(), size); + + // Send request, successful upload will trigger posting metadata. + LLHTTPClient::postRaw(url, data, size, new LLWebProfileResponders::PostImageResponder(), headers); +} + +// static +void LLWebProfile::reportImageUploadStatus(bool ok) +{ + if (mStatusCallback) + { + mStatusCallback(ok); + } +} + +// static +std::string LLWebProfile::getAuthCookie() +{ + return sAuthCookie; +} -- cgit v1.3 From 3b3b6c38a4afe3a061c54cc9fa9f8d7c65dcb990 Mon Sep 17 00:00:00 2001 From: Vadim ProductEngine Date: Mon, 7 Nov 2011 15:12:22 +0200 Subject: STORM-1580 WIP Switched profile feed snapshot format to PNG for better clarity. --- indra/newview/llfloatersnapshot.cpp | 89 ++-------------------- indra/newview/llpanelsnapshot.cpp | 13 ++++ indra/newview/llpanelsnapshotlocal.cpp | 6 +- indra/newview/llpanelsnapshotpostcard.cpp | 2 +- indra/newview/llpanelsnapshotprofile.cpp | 1 + indra/newview/llwebprofile.cpp | 16 +++- .../skins/default/xui/en/panel_snapshot_local.xml | 9 ++- 7 files changed, 39 insertions(+), 97 deletions(-) (limited to 'indra/newview/llwebprofile.cpp') diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 49da41dc0c..d25275f66b 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -849,18 +849,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview ) // delete any existing image previewp->mFormattedImage = NULL; // now create the new one of the appropriate format. - // note: postcards and web hardcoded to use jpeg always. - LLFloaterSnapshot::ESnapshotFormat format; - - if (previewp->getSnapshotType() == SNAPSHOT_POSTCARD || - previewp->getSnapshotType() == SNAPSHOT_WEB) - { - format = LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG; - } - else - { - format = previewp->getSnapshotFormat(); - } + LLFloaterSnapshot::ESnapshotFormat format = previewp->getSnapshotFormat(); lldebugs << "Encoding new image of format " << format << llendl; switch(format) @@ -1062,6 +1051,7 @@ void LLSnapshotLivePreview::regionNameCallback(LLImageJPEG* snapshot, LLSD& meta class LLFloaterSnapshot::Impl { + LOG_CLASS(LLFloaterSnapshot::Impl); public: typedef enum e_status { @@ -1125,8 +1115,6 @@ public: EStatus getStatus() const { return mStatus; } private: - static LLSnapshotLivePreview::ESnapshotType getTypeIndex(const std::string& id); - static LLSD getTypeName(LLSnapshotLivePreview::ESnapshotType index); static LLViewerWindow::ESnapshotType getLayerType(LLFloaterSnapshot* floater); static void comboSetCustom(LLFloaterSnapshot *floater, const std::string& comboname); static void checkAutoSnapshot(LLSnapshotLivePreview* floater, BOOL update_thumbnail = FALSE); @@ -1188,7 +1176,8 @@ LLSnapshotLivePreview::ESnapshotType LLFloaterSnapshot::Impl::getActiveSnapshotT LLFloaterSnapshot::ESnapshotFormat LLFloaterSnapshot::Impl::getImageFormat(LLFloaterSnapshot* floater) { LLPanelSnapshot* active_panel = getActivePanel(floater); - return active_panel ? active_panel->getImageFormat() : LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG; + // FIXME: if the default is not PNG, profile uploads may fail. + return active_panel ? active_panel->getImageFormat() : LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG; } // static @@ -1222,54 +1211,6 @@ LLSnapshotLivePreview* LLFloaterSnapshot::Impl::getPreviewView(LLFloaterSnapshot return previewp; } -// static -LLSnapshotLivePreview::ESnapshotType LLFloaterSnapshot::Impl::getTypeIndex(const std::string& id) -{ - LLSnapshotLivePreview::ESnapshotType index = LLSnapshotLivePreview::SNAPSHOT_POSTCARD; - - if (id == "postcard") - { - index = LLSnapshotLivePreview::SNAPSHOT_POSTCARD; - } - else if (id == "texture") - { - index = LLSnapshotLivePreview::SNAPSHOT_TEXTURE; - } - else if (id == "local") - { - index = LLSnapshotLivePreview::SNAPSHOT_LOCAL; - } - else if (id == "share_to_web") - { - index = LLSnapshotLivePreview::SNAPSHOT_WEB; - } - - return index; -} - -// static -LLSD LLFloaterSnapshot::Impl::getTypeName(LLSnapshotLivePreview::ESnapshotType index) -{ - std::string id; - switch (index) - { - case LLSnapshotLivePreview::SNAPSHOT_WEB: - id = "share_to_web"; - break; - case LLSnapshotLivePreview::SNAPSHOT_POSTCARD: - id = "postcard"; - break; - case LLSnapshotLivePreview::SNAPSHOT_TEXTURE: - id = "texture"; - break; - case LLSnapshotLivePreview::SNAPSHOT_LOCAL: - default: - id = "local"; - break; - } - return LLSD(id); -} - // static LLViewerWindow::ESnapshotType LLFloaterSnapshot::Impl::getLayerType(LLFloaterSnapshot* floater) { @@ -1417,9 +1358,7 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) floater->getChild("postcard_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotPostcardLastResolution")); floater->getChild("texture_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotTextureLastResolution")); floater->getChild("local_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotLocalLastResolution")); -#if 0 floater->getChild("local_format_combo")->selectNthItem(gSavedSettings.getS32("SnapshotFormat")); -#endif // *TODO: Separate settings for Web images from postcards enableAspectRatioCheckbox(floater, shot_type != LLSnapshotLivePreview::SNAPSHOT_TEXTURE && !floater->impl.mAspectRatioCheckOff); @@ -1489,11 +1428,7 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) image_res_tb->setVisible(got_snap); if (got_snap) { -#if 1 LLPointer img = previewp->getEncodedImage(); -#else - LLPointer fimg = previewp->getFormattedImage(); -#endif image_res_tb->setTextArg("[WIDTH]", llformat("%d", img->getWidth())); image_res_tb->setTextArg("[HEIGHT]", llformat("%d", img->getHeight())); } @@ -1532,6 +1467,7 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater) if (previewp) { + lldebugs << "Setting snapshot type (" << shot_type << "), format (" << shot_format << ")" << llendl; previewp->setSnapshotType(shot_type); previewp->setSnapshotFormat(shot_format); previewp->setSnapshotBufferType(layer_type); @@ -2005,20 +1941,6 @@ void LLFloaterSnapshot::Impl::onCommitSnapshotType(LLUICtrl* ctrl, void* data) } #endif -#if 0 -//static. -void LLFloaterSnapshot::Impl::onCommitSnapshotFormat(LLUICtrl* ctrl, void* data) -{ - LLFloaterSnapshot *view = (LLFloaterSnapshot *)data; - if (view) - { - gSavedSettings.setS32("SnapshotFormat", getFormatIndex(view)); - getPreviewView(view)->updateSnapshot(TRUE); - updateControls(view); - } -} -#endif - // Sets the named size combo to "custom" mode. // static void LLFloaterSnapshot::Impl::comboSetCustom(LLFloaterSnapshot* floater, const std::string& comboname) @@ -2262,7 +2184,6 @@ BOOL LLFloaterSnapshot::postBuild() #if 0 childSetCommitCallback("snapshot_type_radio", Impl::onCommitSnapshotType, this); - childSetCommitCallback("local_format_combo", Impl::onCommitSnapshotFormat, this); #endif childSetAction("new_snapshot_btn", Impl::onClickNewSnapshot, this); diff --git a/indra/newview/llpanelsnapshot.cpp b/indra/newview/llpanelsnapshot.cpp index 35627ababe..d00089b181 100644 --- a/indra/newview/llpanelsnapshot.cpp +++ b/indra/newview/llpanelsnapshot.cpp @@ -34,6 +34,7 @@ // newview #include "llsidetraypanelcontainer.h" +#include "llviewercontrol.h" // gSavedSettings // virtual BOOL LLPanelSnapshot::postBuild() @@ -45,7 +46,19 @@ BOOL LLPanelSnapshot::postBuild() // virtual void LLPanelSnapshot::onOpen(const LLSD& key) { + S32 old_format = gSavedSettings.getS32("SnapshotFormat"); + S32 new_format = (S32) getImageFormat(); + + gSavedSettings.setS32("SnapshotFormat", new_format); setCtrlsEnabled(true); + + // Switching panels will likely change image format. + // Not updating preview right away may lead to errors, + // e.g. attempt to send a large BMP image by email. + if (old_format != new_format) + { + LLFloaterSnapshot::getInstance()->notify(LLSD().with("image-format-change", true)); + } } LLFloaterSnapshot::ESnapshotFormat LLPanelSnapshot::getImageFormat() const diff --git a/indra/newview/llpanelsnapshotlocal.cpp b/indra/newview/llpanelsnapshotlocal.cpp index b67c4ec673..e32c34157a 100644 --- a/indra/newview/llpanelsnapshotlocal.cpp +++ b/indra/newview/llpanelsnapshotlocal.cpp @@ -100,7 +100,7 @@ LLFloaterSnapshot::ESnapshotFormat LLPanelSnapshotLocal::getImageFormat() const LLFloaterSnapshot::ESnapshotFormat fmt = LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG; LLComboBox* local_format_combo = getChild("local_format_combo"); - const std::string id = local_format_combo->getSelectedItemLabel(); + const std::string id = local_format_combo->getValue().asString(); if (id == "PNG") { fmt = LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG; @@ -150,10 +150,6 @@ void LLPanelSnapshotLocal::updateCustomResControls() void LLPanelSnapshotLocal::onFormatComboCommit(LLUICtrl* ctrl) { -#if 0 // redundant? - gSavedSettings.setS32("SnapshotFormat", ctrl->getValue().asInteger()); -#endif - // will call updateControls() LLFloaterSnapshot::getInstance()->notify(LLSD().with("image-format-change", true)); } diff --git a/indra/newview/llpanelsnapshotpostcard.cpp b/indra/newview/llpanelsnapshotpostcard.cpp index 9f3f6d7cb6..eead96d67a 100644 --- a/indra/newview/llpanelsnapshotpostcard.cpp +++ b/indra/newview/llpanelsnapshotpostcard.cpp @@ -62,6 +62,7 @@ private: /*virtual*/ std::string getHeightSpinnerName() const { return "postcard_snapshot_height"; } /*virtual*/ std::string getAspectRatioCBName() const { return "postcard_keep_aspect_check"; } /*virtual*/ std::string getImageSizeComboName() const { return "postcard_size_combo"; } + /*virtual*/ LLFloaterSnapshot::ESnapshotFormat getImageFormat() const { return LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG; } /*virtual*/ void updateControls(const LLSD& info); void updateCustomResControls(); ///< Enable/disable custom resolution controls (spinners and checkbox) @@ -123,7 +124,6 @@ BOOL LLPanelSnapshotPostcard::postBuild() // virtual void LLPanelSnapshotPostcard::onOpen(const LLSD& key) { - gSavedSettings.setS32("SnapshotFormat", getImageFormat()); updateCustomResControls(); LLPanelSnapshot::onOpen(key); } diff --git a/indra/newview/llpanelsnapshotprofile.cpp b/indra/newview/llpanelsnapshotprofile.cpp index 33237fd84f..e633049af8 100644 --- a/indra/newview/llpanelsnapshotprofile.cpp +++ b/indra/newview/llpanelsnapshotprofile.cpp @@ -57,6 +57,7 @@ private: /*virtual*/ std::string getHeightSpinnerName() const { return "profile_snapshot_height"; } /*virtual*/ std::string getAspectRatioCBName() const { return "profile_keep_aspect_check"; } /*virtual*/ std::string getImageSizeComboName() const { return "profile_size_combo"; } + /*virtual*/ LLFloaterSnapshot::ESnapshotFormat getImageFormat() const { return LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG; } /*virtual*/ void updateControls(const LLSD& info); void updateCustomResControls(); ///< Enable/disable custom resolution controls (spinners and checkbox) diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp index bb8a9a491b..641f338f2c 100644 --- a/indra/newview/llwebprofile.cpp +++ b/indra/newview/llwebprofile.cpp @@ -31,6 +31,7 @@ // libs #include "llbufferstream.h" #include "llhttpclient.h" +#include "llimagepng.h" #include "llplugincookiestore.h" // newview @@ -219,7 +220,12 @@ void LLWebProfile::setAuthCookie(const std::string& cookie) // static void LLWebProfile::post(LLPointer image, const LLSD& config, const std::string& url) { - // *TODO: make sure it's a jpeg? + if (dynamic_cast(image.get()) == 0) + { + llwarns << "Image to upload is not a PNG" << llendl; + llassert(dynamic_cast(image.get()) != 0); + return; + } const std::string boundary = "----------------------------0123abcdefab"; @@ -259,8 +265,8 @@ void LLWebProfile::post(LLPointer image, const LLSD& config, c << config["success_action_redirect"].asString() << "\r\n"; body << "--" << boundary << "\r\n" - << "Content-Disposition: form-data; name=\"file\"; filename=\"snapshot.jpg\"\r\n" - << "Content-Type: image/jpeg\r\n\r\n"; + << "Content-Disposition: form-data; name=\"file\"; filename=\"snapshot.png\"\r\n" + << "Content-Type: image/png\r\n\r\n"; // Insert the image data. // *FIX: Treating this as a string will probably screw it up ... @@ -293,5 +299,7 @@ void LLWebProfile::reportImageUploadStatus(bool ok) // static std::string LLWebProfile::getAuthCookie() { - return sAuthCookie; + // This is needed to test image uploads on Linux viewer built with OpenSSL 1.0.0 (0.9.8 works fine). + const char* debug_cookie = getenv("LL_SNAPSHOT_COOKIE"); + return debug_cookie ? debug_cookie : sAuthCookie; } diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_local.xml b/indra/newview/skins/default/xui/en/panel_snapshot_local.xml index fd2c735df7..c7a2a88287 100644 --- a/indra/newview/skins/default/xui/en/panel_snapshot_local.xml +++ b/indra/newview/skins/default/xui/en/panel_snapshot_local.xml @@ -128,13 +128,16 @@ width="120"> + name="PNG" + value="PNG" /> + name="JPEG" + value="JPEG" /> + name="BMP" + value="BMP" />