merge changes for 5.1.3-release

master
Oz Linden 2018-04-13 09:45:53 -04:00
commit 2c536cd91d
31 changed files with 240 additions and 1574 deletions

View File

@ -534,3 +534,4 @@ abcab37e1b29414ab8c03af9ca2ab489d809788a 5.0.7-release
ad0e15543836d64d6399d28b32852510435e344a 5.1.0-release
26d9e9bb166a9a417f35b1863223a597af8185fd 5.1.1-release
2eb917875efdfe920680b9049302d0f03721245d 5.1.2-release
7c00e5b6cb3d95712e9d8e29277c805bca2bda90 5.1.3-release

View File

@ -556,9 +556,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>bbdea742f2a89bcd6360e61e01d6be93</string>
<string>118987b1a5b56214cfdbd0c763e180da</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/8207/32592/dullahan-1.1.820_3.3071.1637.gcb6cf75-darwin64-508196.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/15127/97748/dullahan-1.1.1080_3.3325.1750.gaabe4c4-darwin64-513449.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -568,9 +568,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>31e11a74e0d3f1e5e4036cb5fea8d944</string>
<string>2ecc71350b30a1057091b9cd7af18b1c</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/8209/32599/dullahan-1.1.820_3.3071.1634.g9cc59c8-windows-508196.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/15128/97755/dullahan-1.1.1080_3.3325.1750.gaabe4c4-windows-513449.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -580,16 +580,16 @@
<key>archive</key>
<map>
<key>hash</key>
<string>f965d244e7921c06ee79b68a4abcea3b</string>
<string>2ed3e49388514dafb907c59a209d580e</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/8208/32602/dullahan-1.1.820_3.3071.1634.g9cc59c8-windows64-508196.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/15129/97760/dullahan-1.1.1080_3.3325.1750.gaabe4c4-windows64-513449.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>1.1.820_3.3071.1634.g9cc59c8</string>
<string>1.1.1080_3.3325.1750.gaabe4c4</string>
</map>
<key>elfio</key>
<map>
@ -3260,9 +3260,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>f1248b6692dcbb1a42db87ca8d9fed93</string>
<string>4aefe12a3825d1b4b8370986d84792a2</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/13982/87166/viewer_manager-1.0.512801-darwin64-512801.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/15295/98583/viewer_manager-1.0.513540-darwin64-513540.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -3284,9 +3284,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>c174ecc0893f8c193571b1dc80b823ad</string>
<string>db96bc8a83e6577d31657586100bfc35</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/13983/87172/viewer_manager-1.0.512801-windows-512801.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/15298/98589/viewer_manager-1.0.513540-windows-513540.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -3297,7 +3297,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>source_type</key>
<string>hg</string>
<key>version</key>
<string>1.0.512801</string>
<string>1.0.513540</string>
</map>
<key>vlc-bin</key>
<map>
@ -3316,9 +3316,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>c5e6d9440e3a4a12102dd2bbb703963e</string>
<string>e5635e173c75dc0675b48ab5f5e4868b</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/2225/4736/vlc_bin-2.2.4.502214-darwin64-502214.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/12143/71451/vlc_bin-2.2.8.511703-darwin64-511703.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -3340,9 +3340,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>dc37f7cc77a62891bb9ae46c9e19f95e</string>
<string>add560654a53cb1c554044a4fac3c718</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1219/2834/vlc_bin-2.2.4.501207-windows-501207.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/12144/71458/vlc_bin-2.2.8.511703-windows-511703.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -3352,16 +3352,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>148ee599afeba9794de14ca433389504</string>
<string>94bf04b49acc1e1bf2c06e2232f8a083</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1218/2829/vlc_bin-2.2.4.501207-windows64-501207.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/12145/71463/vlc_bin-2.2.8.511703-windows64-511703.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>2.2.4.502214</string>
<string>2.2.8.511703</string>
</map>
<key>xmlrpc-epi</key>
<map>

View File

@ -29,7 +29,6 @@ include_directories(SYSTEM
set(llplugin_SOURCE_FILES
llpluginclassmedia.cpp
llplugincookiestore.cpp
llplugininstance.cpp
llpluginmessage.cpp
llpluginmessagepipe.cpp
@ -43,7 +42,6 @@ set(llplugin_HEADER_FILES
llpluginclassmedia.h
llpluginclassmediaowner.h
llplugincookiestore.h
llplugininstance.h
llpluginmessage.h
llpluginmessageclasses.h
@ -70,20 +68,3 @@ add_library (llplugin ${llplugin_SOURCE_FILES})
add_subdirectory(slplugin)
# Add tests
if (LL_TESTS)
include(LLAddBuildTest)
# UNIT TESTS
SET(llplugin_TEST_SOURCE_FILES
llplugincookiestore.cpp
)
# llplugincookiestore has a dependency on curl, so we need to link the curl library into the test.
set_source_files_properties(
llplugincookiestore.cpp
PROPERTIES
LL_TEST_ADDITIONAL_LIBRARIES "${CURL_LIBRARIES};${NGHTTP2_LIBRARIES}"
)
LL_ADD_PROJECT_UNIT_TESTS(llplugin "${llplugin_TEST_SOURCE_FILES}")
endif (LL_TESTS)

View File

@ -31,6 +31,9 @@
#include "llpluginclassmedia.h"
#include "llpluginmessageclasses.h"
#include "llcontrol.h"
extern LLControlGroup gSavedSettings;
static int LOW_PRIORITY_TEXTURE_SIZE_DEFAULT = 256;
@ -792,15 +795,22 @@ F64 LLPluginClassMedia::getCPUUsage()
return result;
}
void LLPluginClassMedia::sendPickFileResponse(const std::string &file)
void LLPluginClassMedia::sendPickFileResponse(const std::vector<std::string> files)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file_response");
message.setValue("file", file);
if(mPlugin && mPlugin->isBlocked())
{
// If the plugin sent a blocking pick-file request, the response should unblock it.
message.setValueBoolean("blocking_response", true);
}
LLSD file_list = LLSD::emptyArray();
for (std::vector<std::string>::const_iterator in_iter = files.begin(); in_iter != files.end(); ++in_iter)
{
file_list.append(LLSD::String(*in_iter));
}
message.setValueLLSD("file_list", file_list);
sendMessage(message);
}
@ -836,11 +846,17 @@ void LLPluginClassMedia::paste()
sendMessage(message);
}
void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path_cache, const std::string &user_data_path_cookies)
void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path_cache,
const std::string &user_data_path_cookies,
const std::string &user_data_path_cef_log)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "set_user_data_path");
message.setValue("cache_path", user_data_path_cache);
message.setValue("cookies_path", user_data_path_cookies);
message.setValue("cef_log_file", user_data_path_cef_log);
bool cef_verbose_log = gSavedSettings.getBOOL("CefVerboseLog");
message.setValueBoolean("cef_verbose_log", cef_verbose_log);
sendMessage(message);
}
@ -1090,6 +1106,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
}
else if(message_name == "pick_file")
{
mIsMultipleFilePick = message.getValueBoolean("multiple_files");
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PICK_FILE_REQUEST);
}
else if(message_name == "auth_request")
@ -1151,7 +1168,12 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
{
mClickURL = message.getValue("uri");
mClickTarget = message.getValue("target");
mClickUUID = message.getValue("uuid");
// need a link to have a UUID that identifies it to a system further
// upstream - plugin could make it but we have access to LLUUID here
// so why don't we use it
mClickUUID = LLUUID::generateNewID().asString();
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_HREF);
}
else if(message_name == "click_nofollow")
@ -1166,13 +1188,6 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
mStatusCode = message.getValueS32("status_code");
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAVIGATE_ERROR_PAGE);
}
else if(message_name == "cookie_set")
{
if(mOwner)
{
mOwner->handleCookieSet(this, message.getValue("cookie"));
}
}
else if(message_name == "close_request")
{
mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLOSE_REQUEST);
@ -1287,16 +1302,9 @@ void LLPluginClassMedia::clear_cookies()
sendMessage(message);
}
void LLPluginClassMedia::set_cookies(const std::string &cookies)
void LLPluginClassMedia::cookies_enabled(bool enable)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_cookies");
message.setValue("cookies", cookies);
sendMessage(message);
}
void LLPluginClassMedia::enable_cookies(bool enable)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "enable_cookies");
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "cookies_enabled");
message.setValueBoolean("enable", enable);
sendMessage(message);
}

View File

@ -176,7 +176,7 @@ public:
F64 getCPUUsage();
void sendPickFileResponse(const std::string &file);
void sendPickFileResponse(const std::vector<std::string> files);
void sendAuthResponse(bool ok, const std::string &username, const std::string &password);
@ -195,7 +195,7 @@ public:
bool canPaste() const { return mCanPaste; };
// These can be called before init(), and they will be queued and sent before the media init message.
void setUserDataPath(const std::string &user_data_path_cache, const std::string &user_data_path_cookies);
void setUserDataPath(const std::string &user_data_path_cache, const std::string &user_data_path_cookies, const std::string &user_data_path_cef_log);
void setLanguageCode(const std::string &language_code);
void setPluginsEnabled(const bool enabled);
void setJavascriptEnabled(const bool enabled);
@ -210,7 +210,7 @@ public:
void clear_cache();
void clear_cookies();
void set_cookies(const std::string &cookies);
void enable_cookies(bool enable);
void cookies_enabled(bool enable);
void proxy_setup(bool enable, const std::string &host = LLStringUtil::null, int port = 0);
void browse_stop();
void browse_reload(bool ignore_cache = false);
@ -277,6 +277,9 @@ public:
std::string getAuthURL() const { return mAuthURL; };
std::string getAuthRealm() const { return mAuthRealm; };
// These are valid during MEDIA_EVENT_PICK_FILE_REQUEST
bool getIsMultipleFilePick() const { return mIsMultipleFilePick; }
// These are valid during MEDIA_EVENT_LINK_HOVERED
std::string getHoverText() const { return mHoverText; };
std::string getHoverLink() const { return mHoverLink; };
@ -435,6 +438,7 @@ protected:
std::string mHoverText;
std::string mHoverLink;
std::string mFileDownloadFilename;
bool mIsMultipleFilePick;
/////////////////////////////////////////
// media_time class

View File

@ -1,4 +1,4 @@
/**
/**
* @file llpluginclassmediaowner.h
* @brief LLPluginClassMedia handles interaction with a plugin which knows about the "media" message class.
*
@ -6,21 +6,21 @@
* $LicenseInfo:firstyear=2008&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, 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$
* @endcond
@ -34,18 +34,17 @@
#include <queue>
class LLPluginClassMedia;
class LLPluginCookieStore;
class LLPluginClassMediaOwner
{
public:
typedef enum
{
MEDIA_EVENT_CONTENT_UPDATED, // contents/dirty rect have updated
MEDIA_EVENT_CONTENT_UPDATED, // contents/dirty rect have updated
MEDIA_EVENT_TIME_DURATION_UPDATED, // current time and/or duration have updated
MEDIA_EVENT_SIZE_CHANGED, // media size has changed
MEDIA_EVENT_CURSOR_CHANGED, // plugin has requested a cursor change
MEDIA_EVENT_NAVIGATE_BEGIN, // browser has begun navigation
MEDIA_EVENT_NAVIGATE_COMPLETE, // browser has finished navigation
MEDIA_EVENT_PROGRESS_UPDATED, // browser has updated loading progress
@ -58,8 +57,8 @@ public:
MEDIA_EVENT_CLOSE_REQUEST, // The plugin requested its window be closed (currently hooked up to javascript window.close in webkit)
MEDIA_EVENT_PICK_FILE_REQUEST, // The plugin wants the user to pick a file
MEDIA_EVENT_GEOMETRY_CHANGE, // The plugin requested its window geometry be changed (per the javascript window interface)
MEDIA_EVENT_PLUGIN_FAILED_LAUNCH, // The plugin failed to launch
MEDIA_EVENT_PLUGIN_FAILED_LAUNCH, // The plugin failed to launch
MEDIA_EVENT_PLUGIN_FAILED, // The plugin died unexpectedly
MEDIA_EVENT_AUTH_REQUEST, // The plugin wants to display an auth dialog
@ -69,9 +68,9 @@ public:
MEDIA_EVENT_DEBUG_MESSAGE, // plugin sending back debug information for host to process
MEDIA_EVENT_LINK_HOVERED // Got a "link hovered" event from the plugin
} EMediaEvent;
typedef enum
{
MEDIA_NONE, // Uninitialized -- no useful state
@ -81,12 +80,11 @@ public:
MEDIA_PLAYING, // playing (only for time-based media)
MEDIA_PAUSED, // paused (only for time-based media)
MEDIA_DONE // finished playing (only for time-based media)
} EMediaStatus;
virtual ~LLPluginClassMediaOwner() {};
virtual void handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent /*event*/) {};
virtual void handleCookieSet(LLPluginClassMedia* /*self*/, const std::string &/*cookie*/) {};
};
#endif // LL_LLPLUGINCLASSMEDIAOWNER_H

View File

@ -1,689 +0,0 @@
/**
* @file llplugincookiestore.cpp
* @brief LLPluginCookieStore provides central storage for http cookies used by plugins
*
* @cond
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, 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$
* @endcond
*/
#include "linden_common.h"
#include "llstl.h"
#include "indra_constants.h"
#include "llplugincookiestore.h"
#include <iostream>
// for curl_getdate() (apparently parsing RFC 1123 dates is hard)
#include <curl/curl.h>
LLPluginCookieStore::LLPluginCookieStore():
mHasChangedCookies(false)
{
}
LLPluginCookieStore::~LLPluginCookieStore()
{
clearCookies();
}
LLPluginCookieStore::Cookie::Cookie(const std::string &s, std::string::size_type cookie_start, std::string::size_type cookie_end):
mCookie(s, cookie_start, cookie_end - cookie_start),
mNameStart(0), mNameEnd(0),
mValueStart(0), mValueEnd(0),
mDomainStart(0), mDomainEnd(0),
mPathStart(0), mPathEnd(0),
mDead(false), mChanged(true)
{
}
LLPluginCookieStore::Cookie *LLPluginCookieStore::Cookie::createFromString(const std::string &s, std::string::size_type cookie_start, std::string::size_type cookie_end, const std::string &host)
{
Cookie *result = new Cookie(s, cookie_start, cookie_end);
if(!result->parse(host))
{
delete result;
result = NULL;
}
return result;
}
std::string LLPluginCookieStore::Cookie::getKey() const
{
std::string result;
if(mDomainEnd > mDomainStart)
{
result += mCookie.substr(mDomainStart, mDomainEnd - mDomainStart);
}
result += ';';
if(mPathEnd > mPathStart)
{
result += mCookie.substr(mPathStart, mPathEnd - mPathStart);
}
result += ';';
result += mCookie.substr(mNameStart, mNameEnd - mNameStart);
return result;
}
std::string LLPluginCookieStore::Cookie::getDomain() const
{
std::string result;
if(mDomainEnd > mDomainStart)
{
result += mCookie.substr(mDomainStart, mDomainEnd - mDomainStart);
}
return result;
}
bool LLPluginCookieStore::Cookie::parse(const std::string &host)
{
bool first_field = true;
std::string::size_type cookie_end = mCookie.size();
std::string::size_type field_start = 0;
LL_DEBUGS("CookieStoreParse") << "parsing cookie: " << mCookie << LL_ENDL;
while(field_start < cookie_end)
{
// Finding the start of the next field requires honoring special quoting rules
// see the definition of 'quoted-string' in rfc2616 for details
std::string::size_type next_field_start = findFieldEnd(field_start);
// The end of this field should not include the terminating ';' or any trailing whitespace
std::string::size_type field_end = mCookie.find_last_not_of("; ", next_field_start);
if(field_end == std::string::npos || field_end < field_start)
{
// This field was empty or all whitespace. Set end = start so it shows as empty.
field_end = field_start;
}
else if (field_end < next_field_start)
{
// we actually want the index of the char _after_ what 'last not of' found
++field_end;
}
// find the start of the actual name (skip separator and possible whitespace)
std::string::size_type name_start = mCookie.find_first_not_of("; ", field_start);
if(name_start == std::string::npos || name_start > next_field_start)
{
// Again, nothing but whitespace.
name_start = field_start;
}
// the name and value are separated by the first equals sign
std::string::size_type name_value_sep = mCookie.find_first_of("=", name_start);
if(name_value_sep == std::string::npos || name_value_sep > field_end)
{
// No separator found, so this is a field without an =
name_value_sep = field_end;
}
// the name end is before the name-value separator
std::string::size_type name_end = mCookie.find_last_not_of("= ", name_value_sep);
if(name_end == std::string::npos || name_end < name_start)
{
// I'm not sure how we'd hit this case... it seems like it would have to be an empty name.
name_end = name_start;
}
else if (name_end < name_value_sep)
{
// we actually want the index of the char _after_ what 'last not of' found
++name_end;
}
// Value is between the name-value sep and the end of the field.
std::string::size_type value_start = mCookie.find_first_not_of("= ", name_value_sep);
if(value_start == std::string::npos || value_start > field_end)
{
// All whitespace or empty value
value_start = field_end;
}
std::string::size_type value_end = mCookie.find_last_not_of("; ", field_end);
if(value_end == std::string::npos || value_end < value_start)
{
// All whitespace or empty value
value_end = value_start;
}
else if (value_end < field_end)
{
// we actually want the index of the char _after_ what 'last not of' found
++value_end;
}
LL_DEBUGS("CookieStoreParse")
<< " field name: \"" << mCookie.substr(name_start, name_end - name_start)
<< "\", value: \"" << mCookie.substr(value_start, value_end - value_start) << "\""
<< LL_ENDL;
// See whether this field is one we know
if(first_field)
{
// The first field is the name=value pair
mNameStart = name_start;
mNameEnd = name_end;
mValueStart = value_start;
mValueEnd = value_end;
first_field = false;
}
else
{
// Subsequent fields must come from the set in rfc2109
if(matchName(name_start, name_end, "expires"))
{
std::string date_string(mCookie, value_start, value_end - value_start);
// If the cookie contains an "expires" field, it MUST contain a parsable date.
// HACK: LLDate apparently can't PARSE an rfc1123-format date, even though it can GENERATE one.
// The curl function curl_getdate can do this, but I'm hesitant to unilaterally introduce a curl dependency in LLDate.
#if 1
time_t date = curl_getdate(date_string.c_str(), NULL );
mDate.secondsSinceEpoch((F64)date);
LL_DEBUGS("CookieStoreParse") << " expire date parsed to: " << mDate.asRFC1123() << LL_ENDL;
#else
// This doesn't work (rfc1123-format dates cause it to fail)
if(!mDate.fromString(date_string))
{
// Date failed to parse.
LL_WARNS("CookieStoreParse") << "failed to parse cookie's expire date: " << date << LL_ENDL;
return false;
}
#endif
}
else if(matchName(name_start, name_end, "domain"))
{
mDomainStart = value_start;
mDomainEnd = value_end;
}
else if(matchName(name_start, name_end, "path"))
{
mPathStart = value_start;
mPathEnd = value_end;
}
else if(matchName(name_start, name_end, "max-age"))
{
// TODO: how should we handle this?
}
else if(matchName(name_start, name_end, "secure"))
{
// We don't care about the value of this field (yet)
}
else if(matchName(name_start, name_end, "version"))
{
// We don't care about the value of this field (yet)
}
else if(matchName(name_start, name_end, "comment"))
{
// We don't care about the value of this field (yet)
}
else if(matchName(name_start, name_end, "httponly"))
{
// We don't care about the value of this field (yet)
}
else
{
// An unknown field is a parse failure
LL_WARNS("CookieStoreParse") << "unexpected field name: " << mCookie.substr(name_start, name_end - name_start) << LL_ENDL;
return false;
}
}
// move on to the next field, skipping this field's separator and any leading whitespace
field_start = mCookie.find_first_not_of("; ", next_field_start);
}
// The cookie MUST have a name
if(mNameEnd <= mNameStart)
return false;
// If the cookie doesn't have a domain, add the current host as the domain.
if(mDomainEnd <= mDomainStart)
{
if(host.empty())
{
// no domain and no current host -- this is a parse failure.
return false;
}
// Figure out whether this cookie ended with a ";" or not...
std::string::size_type last_char = mCookie.find_last_not_of(" ");
if((last_char != std::string::npos) && (mCookie[last_char] != ';'))
{
mCookie += ";";
}
mCookie += " domain=";
mDomainStart = mCookie.size();
mCookie += host;
mDomainEnd = mCookie.size();
LL_DEBUGS("CookieStoreParse") << "added domain (" << mDomainStart << " to " << mDomainEnd << "), new cookie is: " << mCookie << LL_ENDL;
}
// If the cookie doesn't have a path, add "/".
if(mPathEnd <= mPathStart)
{
// Figure out whether this cookie ended with a ";" or not...
std::string::size_type last_char = mCookie.find_last_not_of(" ");
if((last_char != std::string::npos) && (mCookie[last_char] != ';'))
{
mCookie += ";";
}
mCookie += " path=";
mPathStart = mCookie.size();
mCookie += "/";
mPathEnd = mCookie.size();
LL_DEBUGS("CookieStoreParse") << "added path (" << mPathStart << " to " << mPathEnd << "), new cookie is: " << mCookie << LL_ENDL;
}
return true;
}
std::string::size_type LLPluginCookieStore::Cookie::findFieldEnd(std::string::size_type start, std::string::size_type end)
{
std::string::size_type result = start;
if(end == std::string::npos)
end = mCookie.size();
bool in_quotes = false;
for(; (result < end); result++)
{
switch(mCookie[result])
{
case '\\':
if(in_quotes)
result++; // The next character is backslash-quoted. Skip over it.
break;
case '"':
in_quotes = !in_quotes;
break;
case ';':
if(!in_quotes)
return result;
break;
}
}
// If we got here, no ';' was found.
return end;
}
bool LLPluginCookieStore::Cookie::matchName(std::string::size_type start, std::string::size_type end, const char *name)
{
// NOTE: this assumes 'name' is already in lowercase. The code which uses it should be able to arrange this...
while((start < end) && (*name != '\0'))
{
if(tolower(mCookie[start]) != *name)
return false;
start++;
name++;
}
// iff both strings hit the end at the same time, they're equal.
return ((start == end) && (*name == '\0'));
}
std::string LLPluginCookieStore::getAllCookies()
{
std::stringstream result;
writeAllCookies(result);
return result.str();
}
void LLPluginCookieStore::writeAllCookies(std::ostream& s)
{
cookie_map_t::iterator iter;
for(iter = mCookies.begin(); iter != mCookies.end(); iter++)
{
// Don't return expired cookies
if(!iter->second->isDead())
{
s << (iter->second->getCookie()) << "\n";
}
}
}
std::string LLPluginCookieStore::getPersistentCookies()
{
std::stringstream result;
writePersistentCookies(result);
return result.str();
}
void LLPluginCookieStore::writePersistentCookies(std::ostream& s)
{
cookie_map_t::iterator iter;
for(iter = mCookies.begin(); iter != mCookies.end(); iter++)
{
// Don't return expired cookies or session cookies
if(!iter->second->isDead() && !iter->second->isSessionCookie())
{
s << iter->second->getCookie() << "\n";
}
}
}
std::string LLPluginCookieStore::getChangedCookies(bool clear_changed)
{
std::stringstream result;
writeChangedCookies(result, clear_changed);
return result.str();
}
void LLPluginCookieStore::writeChangedCookies(std::ostream& s, bool clear_changed)
{
if(mHasChangedCookies)
{
LL_DEBUGS() << "returning changed cookies: " << LL_ENDL;
cookie_map_t::iterator iter;
for(iter = mCookies.begin(); iter != mCookies.end(); )
{
cookie_map_t::iterator next = iter;
next++;
// Only return cookies marked as "changed"
if(iter->second->isChanged())
{
s << iter->second->getCookie() << "\n";
LL_DEBUGS() << " " << iter->second->getCookie() << LL_ENDL;
// If requested, clear the changed mark
if(clear_changed)
{
if(iter->second->isDead())
{
// If this cookie was previously marked dead, it needs to be removed entirely.
delete iter->second;
mCookies.erase(iter);
}
else
{
// Not dead, just mark as not changed.
iter->second->setChanged(false);
}
}
}
iter = next;
}
}
if(clear_changed)
mHasChangedCookies = false;
}
void LLPluginCookieStore::setAllCookies(const std::string &cookies, bool mark_changed)
{
clearCookies();
setCookies(cookies, mark_changed);
}
void LLPluginCookieStore::readAllCookies(std::istream& s, bool mark_changed)
{
clearCookies();
readCookies(s, mark_changed);
}
void LLPluginCookieStore::setCookies(const std::string &cookies, bool mark_changed)
{
std::string::size_type start = 0;
while(start != std::string::npos)
{
std::string::size_type end = cookies.find_first_of("\r\n", start);
if(end > start)
{
// The line is non-empty. Try to create a cookie from it.
setOneCookie(cookies, start, end, mark_changed);
}
start = cookies.find_first_not_of("\r\n ", end);
}
}
void LLPluginCookieStore::setCookiesFromHost(const std::string &cookies, const std::string &host, bool mark_changed)
{
std::string::size_type start = 0;
while(start != std::string::npos)
{
std::string::size_type end = cookies.find_first_of("\r\n", start);
if(end > start)
{
// The line is non-empty. Try to create a cookie from it.
setOneCookie(cookies, start, end, mark_changed, host);
}
start = cookies.find_first_not_of("\r\n ", end);
}
}
void LLPluginCookieStore::readCookies(std::istream& s, bool mark_changed)
{
std::string line;
while(s.good() && !s.eof())
{
std::getline(s, line);
if(!line.empty())
{
// Try to create a cookie from this line.
setOneCookie(line, 0, std::string::npos, mark_changed);
}
}
}
std::string LLPluginCookieStore::quoteString(const std::string &s)
{
std::stringstream result;
result << '"';
for(std::string::size_type i = 0; i < s.size(); ++i)
{
char c = s[i];
switch(c)
{
// All these separators need to be quoted in HTTP headers, according to section 2.2 of rfc 2616:
case '(': case ')': case '<': case '>': case '@':
case ',': case ';': case ':': case '\\': case '"':
case '/': case '[': case ']': case '?': case '=':
case '{': case '}': case ' ': case '\t':
result << '\\';
break;
}
result << c;
}
result << '"';
return result.str();
}
std::string LLPluginCookieStore::unquoteString(const std::string &s)
{
std::stringstream result;
bool in_quotes = false;
for(std::string::size_type i = 0; i < s.size(); ++i)
{
char c = s[i];
switch(c)
{
case '\\':
if(in_quotes)
{
// The next character is backslash-quoted. Pass it through untouched.
++i;
if(i < s.size())
{
result << s[i];
}
continue;
}
break;
case '"':
in_quotes = !in_quotes;
continue;
break;
}
result << c;
}
return result.str();
}
// The flow for deleting a cookie is non-obvious enough that I should call it out here...
// Deleting a cookie is done by setting a cookie with the same name, path, and domain, but with an expire timestamp in the past.
// (This is exactly how a web server tells a browser to delete a cookie.)
// When deleting with mark_changed set to true, this replaces the existing cookie in the list with an entry that's marked both dead and changed.
// Some time later when writeChangedCookies() is called with clear_changed set to true, the dead cookie is deleted from the list after being returned, so that the
// delete operation (in the form of the expired cookie) is passed along.
void LLPluginCookieStore::setOneCookie(const std::string &s, std::string::size_type cookie_start, std::string::size_type cookie_end, bool mark_changed, const std::string &host)
{
Cookie *cookie = Cookie::createFromString(s, cookie_start, cookie_end, host);
if(cookie)
{
LL_DEBUGS("CookieStoreUpdate") << "setting cookie: " << cookie->getCookie() << LL_ENDL;
// Create a key for this cookie
std::string key = cookie->getKey();
// Check to see whether this cookie should have expired
if(!cookie->isSessionCookie() && (cookie->getDate() < LLDate::now()))
{
// This cookie has expired.
if(mark_changed)
{
// If we're marking cookies as changed, we should keep it anyway since we'll need to send it out with deltas.
cookie->setDead(true);
LL_DEBUGS("CookieStoreUpdate") << " marking dead" << LL_ENDL;
}
else
{
// If we're not marking cookies as changed, we don't need to keep this cookie at all.
// If the cookie was already in the list, delete it.
removeCookie(key);
delete cookie;
cookie = NULL;
LL_DEBUGS("CookieStoreUpdate") << " removing" << LL_ENDL;
}
}
if(cookie)
{
// If it already exists in the map, replace it.
cookie_map_t::iterator iter = mCookies.find(key);
if(iter != mCookies.end())
{
if(iter->second->getCookie() == cookie->getCookie())
{
// The new cookie is identical to the old -- don't mark as changed.
// Just leave the old one in the map.
delete cookie;
cookie = NULL;
LL_DEBUGS("CookieStoreUpdate") << " unchanged" << LL_ENDL;
}
else
{
// A matching cookie was already in the map. Replace it.
delete iter->second;
iter->second = cookie;
cookie->setChanged(mark_changed);
if(mark_changed)
mHasChangedCookies = true;
LL_DEBUGS("CookieStoreUpdate") << " replacing" << LL_ENDL;
}
}
else
{
// The cookie wasn't in the map. Insert it.
mCookies.insert(std::make_pair(key, cookie));
cookie->setChanged(mark_changed);
if(mark_changed)
mHasChangedCookies = true;
LL_DEBUGS("CookieStoreUpdate") << " adding" << LL_ENDL;
}
}
}
else
{
LL_WARNS("CookieStoreUpdate") << "failed to parse cookie: " << s.substr(cookie_start, cookie_end - cookie_start) << LL_ENDL;
}
}
void LLPluginCookieStore::clearCookies()
{
std::for_each(mCookies.begin(), mCookies.end(), DeletePairedPointer());
mCookies.clear();
}
void LLPluginCookieStore::removeCookie(const std::string &key)
{
cookie_map_t::iterator iter = mCookies.find(key);
if(iter != mCookies.end())
{
delete iter->second;
mCookies.erase(iter);
}
}
void LLPluginCookieStore::removeCookiesByDomain(const std::string &domain)
{
cookie_map_t::iterator iter = mCookies.begin();
while(iter != mCookies.end())
{
if(iter->second->getDomain() == domain)
{
cookie_map_t::iterator doErase = iter;
iter++;
delete doErase->second;
mCookies.erase(doErase);
}
else
{
iter++;
}
}
}

View File

@ -1,123 +0,0 @@
/**
* @file llplugincookiestore.h
* @brief LLPluginCookieStore provides central storage for http cookies used by plugins
*
* @cond
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, 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$
* @endcond
*/
#ifndef LL_LLPLUGINCOOKIESTORE_H
#define LL_LLPLUGINCOOKIESTORE_H
#include "lldate.h"
#include <map>
#include <string>
#include <iostream>
class LLPluginCookieStore
{
LOG_CLASS(LLPluginCookieStore);
public:
LLPluginCookieStore();
~LLPluginCookieStore();
// gets all cookies currently in storage -- use when initializing a plugin
std::string getAllCookies();
void writeAllCookies(std::ostream& s);
// gets only persistent cookies (i.e. not session cookies) -- use when writing cookies to a file
std::string getPersistentCookies();
void writePersistentCookies(std::ostream& s);
// gets cookies which are marked as "changed" -- use when sending periodic updates to plugins
std::string getChangedCookies(bool clear_changed = true);
void writeChangedCookies(std::ostream& s, bool clear_changed = true);
// (re)initializes internal data structures and bulk-sets cookies -- use when reading cookies from a file
void setAllCookies(const std::string &cookies, bool mark_changed = false);
void readAllCookies(std::istream& s, bool mark_changed = false);
// sets one or more cookies (without reinitializing anything) -- use when receiving cookies from a plugin
void setCookies(const std::string &cookies, bool mark_changed = true);
void readCookies(std::istream& s, bool mark_changed = true);
// sets one or more cookies (without reinitializing anything), supplying a hostname the cookies came from -- use when setting a cookie manually
void setCookiesFromHost(const std::string &cookies, const std::string &host, bool mark_changed = true);
// quote or unquote a string as per the definition of 'quoted-string' in rfc2616
static std::string quoteString(const std::string &s);
static std::string unquoteString(const std::string &s);
void removeCookiesByDomain(const std::string &domain);
private:
void setOneCookie(const std::string &s, std::string::size_type cookie_start, std::string::size_type cookie_end, bool mark_changed, const std::string &host = LLStringUtil::null);
class Cookie
{
public:
static Cookie *createFromString(const std::string &s, std::string::size_type cookie_start = 0, std::string::size_type cookie_end = std::string::npos, const std::string &host = LLStringUtil::null);
// Construct a string from the cookie that uniquely represents it, to be used as a key in a std::map.
std::string getKey() const;
std::string getDomain() const;
const std::string &getCookie() const { return mCookie; };
bool isSessionCookie() const { return mDate.isNull(); };
bool isDead() const { return mDead; };
void setDead(bool dead) { mDead = dead; };
bool isChanged() const { return mChanged; };
void setChanged(bool changed) { mChanged = changed; };
const LLDate &getDate() const { return mDate; };
private:
Cookie(const std::string &s, std::string::size_type cookie_start = 0, std::string::size_type cookie_end = std::string::npos);
bool parse(const std::string &host);
std::string::size_type findFieldEnd(std::string::size_type start = 0, std::string::size_type end = std::string::npos);
bool matchName(std::string::size_type start, std::string::size_type end, const char *name);
std::string mCookie; // The full cookie, in RFC 2109 string format
LLDate mDate; // The expiration date of the cookie. For session cookies, this will be a null date (mDate.isNull() is true).
// Start/end indices of various parts of the cookie string. Stored as indices into the string to save space and time.
std::string::size_type mNameStart, mNameEnd;
std::string::size_type mValueStart, mValueEnd;
std::string::size_type mDomainStart, mDomainEnd;
std::string::size_type mPathStart, mPathEnd;
bool mDead;
bool mChanged;
};
typedef std::map<std::string, Cookie*> cookie_map_t;
cookie_map_t mCookies;
bool mHasChangedCookies;
void clearCookies();
void removeCookie(const std::string &key);
};
#endif // LL_LLPLUGINCOOKIESTORE_H

View File

@ -1,207 +0,0 @@
/**
* @file llplugincookiestore_test.cpp
* @brief Unit tests for LLPluginCookieStore.
*
* @cond
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, 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$
* @endcond
*/
#include "linden_common.h"
#include <list>
#include "../test/lltut.h"
#include "../llplugincookiestore.h"
namespace tut
{
// Main Setup
struct LLPluginCookieStoreFixture
{
LLPluginCookieStoreFixture()
{
// We need dates definitively in the past and the future to properly test cookie expiration.
LLDate now = LLDate::now();
LLDate past(now.secondsSinceEpoch() - (60.0 * 60.0 * 24.0)); // 1 day in the past
LLDate future(now.secondsSinceEpoch() + (60.0 * 60.0 * 24.0)); // 1 day in the future
mPastString = past.asRFC1123();
mFutureString = future.asRFC1123();
}
std::string mPastString;
std::string mFutureString;
LLPluginCookieStore mCookieStore;
// List of cookies used for validation
std::list<std::string> mCookies;
// This sets up mCookies from a string returned by one of the functions in LLPluginCookieStore
void setCookies(const std::string &cookies)
{
mCookies.clear();
std::string::size_type start = 0;
while(start != std::string::npos)
{
std::string::size_type end = cookies.find_first_of("\r\n", start);
if(end > start)
{
std::string line(cookies, start, end - start);
if(line.find_first_not_of("\r\n\t ") != std::string::npos)
{
// The line has some non-whitespace characters. Save it to the list.
mCookies.push_back(std::string(cookies, start, end - start));
}
}
start = cookies.find_first_not_of("\r\n ", end);
}
}
// This ensures that a cookie matching the one passed is in the list.
void ensureCookie(const std::string &cookie)
{
std::list<std::string>::iterator iter;
for(iter = mCookies.begin(); iter != mCookies.end(); iter++)
{
if(*iter == cookie)
{
// Found the cookie
// TODO: this should do a smarter equality comparison on the two cookies, instead of just a string compare.
return;
}
}
// Didn't find this cookie
std::string message = "cookie not found: ";
message += cookie;
ensure(message, false);
}
// This ensures that the number of cookies in the list matches what's expected.
void ensureSize(const std::string &message, size_t size)
{
if(mCookies.size() != size)
{
std::stringstream full_message;
full_message << message << " (expected " << size << ", actual " << mCookies.size() << ")";
ensure(full_message.str(), false);
}
}
};
typedef test_group<LLPluginCookieStoreFixture> factory;
typedef factory::object object;
factory tf("LLPluginCookieStore");
// Tests
template<> template<>
void object::test<1>()
{
// Test 1: cookie uniqueness and update lists.
// Valid, distinct cookies:
std::string cookie01 = "cookieA=value; domain=example.com; path=/";
std::string cookie02 = "cookieB=value; Domain=example.com; Path=/; Max-Age=10; Secure; Version=1; Comment=foo!; HTTPOnly"; // cookie with every supported field, in different cases.
std::string cookie03 = "cookieA=value; domain=foo.example.com; path=/"; // different domain
std::string cookie04 = "cookieA=value; domain=example.com; path=/bar/"; // different path
std::string cookie05 = "cookieC; domain=example.com; path=/"; // empty value
std::string cookie06 = "cookieD=value; domain=example.com; path=/; expires="; // different name, persistent cookie
cookie06 += mFutureString;
mCookieStore.setCookies(cookie01);
mCookieStore.setCookies(cookie02);
mCookieStore.setCookies(cookie03);
mCookieStore.setCookies(cookie04);
mCookieStore.setCookies(cookie05);
mCookieStore.setCookies(cookie06);
// Invalid cookies (these will get parse errors and not be added to the store)
std::string badcookie01 = "cookieD=value; domain=example.com; path=/; foo=bar"; // invalid field name
std::string badcookie02 = "cookieE=value; path=/"; // no domain
mCookieStore.setCookies(badcookie01);
mCookieStore.setCookies(badcookie02);
// All cookies added so far should have been marked as "changed"
setCookies(mCookieStore.getChangedCookies());
ensureSize("count of changed cookies", 6);
ensureCookie(cookie01);
ensureCookie(cookie02);
ensureCookie(cookie03);
ensureCookie(cookie04);
ensureCookie(cookie05);
ensureCookie(cookie06);
// Save off the current state of the cookie store (we'll restore it later)
std::string savedCookies = mCookieStore.getAllCookies();
// Test replacing cookies
std::string cookie01a = "cookieA=newvalue; domain=example.com; path=/"; // updated value
std::string cookie02a = "cookieB=newvalue; domain=example.com; path=/; expires="; // remove cookie (by setting an expire date in the past)
cookie02a += mPastString;
mCookieStore.setCookies(cookie01a);
mCookieStore.setCookies(cookie02a);
// test for getting changed cookies
setCookies(mCookieStore.getChangedCookies());
ensureSize("count of updated cookies", 2);
ensureCookie(cookie01a);
ensureCookie(cookie02a);
// and for the state of the store after getting changed cookies
setCookies(mCookieStore.getAllCookies());
ensureSize("count of valid cookies", 5);
ensureCookie(cookie01a);
ensureCookie(cookie03);
ensureCookie(cookie04);
ensureCookie(cookie05);
ensureCookie(cookie06);
// Check that only the persistent cookie is returned here
setCookies(mCookieStore.getPersistentCookies());
ensureSize("count of persistent cookies", 1);
ensureCookie(cookie06);
// Restore the cookie store to a previous state and verify
mCookieStore.setAllCookies(savedCookies);
// Since setAllCookies defaults to not marking cookies as changed, this list should be empty.
setCookies(mCookieStore.getChangedCookies());
ensureSize("count of changed cookies after restore", 0);
// Verify that the restore worked as it should have.
setCookies(mCookieStore.getAllCookies());
ensureSize("count of restored cookies", 6);
ensureCookie(cookie01);
ensureCookie(cookie02);
ensureCookie(cookie03);
ensureCookie(cookie04);
ensureCookie(cookie05);
ensureCookie(cookie06);
}
}

View File

@ -703,7 +703,7 @@ namespace LLNotificationComparators
{
struct orderByUUID
{
bool operator()(LLNotificationPtr lhs, LLNotificationPtr rhs)
bool operator()(LLNotificationPtr lhs, LLNotificationPtr rhs) const
{
return lhs->id() < rhs->id();
}

View File

@ -38,6 +38,7 @@
#include "media_plugin_base.h"
#include <functional>
#include <chrono>
#include "dullahan.h"
@ -64,12 +65,12 @@ private:
void onLoadStartCallback();
void onRequestExitCallback();
void onLoadEndCallback(int httpStatusCode);
void onLoadError(int status, const std::string error_text);
void onAddressChangeCallback(std::string url);
void onNavigateURLCallback(std::string url, std::string target);
void onOpenPopupCallback(std::string url, std::string target);
bool onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password);
void onCursorChangedCallback(dullahan::ECursorType type);
void onFileDownloadCallback(std::string filename);
const std::string onFileDialogCallback();
const std::vector<std::string> onFileDialog(dullahan::EFileDialogType dialog_type, const std::string dialog_title, const std::string default_file, const std::string dialog_accept_filter, bool& use_default);
void postDebugMessage(const std::string& msg);
void authResponse(LLPluginMessage &message);
@ -95,7 +96,9 @@ private:
bool mCanPaste;
std::string mCachePath;
std::string mCookiePath;
std::string mPickedFile;
std::string mCefLogFile;
bool mCefLogVerbose;
std::vector<std::string> mPickedFiles;
VolumeCatcher mVolumeCatcher;
F32 mCurVolume;
dullahan* mCEFLib;
@ -115,7 +118,7 @@ MediaPluginBase(host_send_func, host_user_data)
mCookiesEnabled = true;
mPluginsEnabled = false;
mJavascriptEnabled = true;
mDisableGPU = true;
mDisableGPU = false;
mUserAgentSubtring = "";
mAuthUsername = "";
mAuthPassword = "";
@ -125,7 +128,9 @@ MediaPluginBase(host_send_func, host_user_data)
mCanPaste = false;
mCachePath = "";
mCookiePath = "";
mPickedFile = "";
mCefLogFile = "";
mCefLogVerbose = false;
mPickedFiles.clear();
mCurVolume = 0.0;
mCEFLib = new dullahan();
@ -166,6 +171,10 @@ void MediaPluginCEF::onPageChangedCallback(const unsigned char* pixels, int x, i
{
memcpy(mPixels, pixels, mWidth * mHeight * mDepth);
}
else
{
mCEFLib->setSize(mWidth, mHeight);
}
setDirty(0, 0, mWidth, mHeight);
}
}
@ -208,6 +217,21 @@ void MediaPluginCEF::onLoadStartCallback()
sendMessage(message);
}
/////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginCEF::onLoadError(int status, const std::string error_text)
{
std::stringstream msg;
msg << "<b>Loading error!</b>";
msg << "<p>";
msg << "Message: " << error_text;
msg << "<br>";
msg << "Code: " << status;
mCEFLib->showBrowserMessage(msg.str());
}
////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginCEF::onRequestExitCallback()
@ -241,12 +265,11 @@ void MediaPluginCEF::onAddressChangeCallback(std::string url)
////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginCEF::onNavigateURLCallback(std::string url, std::string target)
void MediaPluginCEF::onOpenPopupCallback(std::string url, std::string target)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_href");
message.setValue("uri", url);
message.setValue("target", target);
message.setValue("uuid", ""); // not used right now
sendMessage(message);
}
@ -285,30 +308,52 @@ bool MediaPluginCEF::onHTTPAuthCallback(const std::string host, const std::strin
////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginCEF::onFileDownloadCallback(const std::string filename)
const std::vector<std::string> MediaPluginCEF::onFileDialog(dullahan::EFileDialogType dialog_type, const std::string dialog_title, const std::string default_file, std::string dialog_accept_filter, bool& use_default)
{
mAuthOK = false;
// do not use the default CEF file picker
use_default = false;
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "file_download");
message.setValue("filename", filename);
if (dialog_type == dullahan::FD_OPEN_FILE)
{
mPickedFiles.clear();
sendMessage(message);
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file");
message.setValueBoolean("blocking_request", true);
message.setValueBoolean("multiple_files", false);
sendMessage(message);
return mPickedFiles;
}
else if (dialog_type == dullahan::FD_OPEN_MULTIPLE_FILES)
{
mPickedFiles.clear();
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file");
message.setValueBoolean("blocking_request", true);
message.setValueBoolean("multiple_files", true);
sendMessage(message);
return mPickedFiles;
}
else if (dialog_type == dullahan::FD_SAVE_FILE)
{
mAuthOK = false;
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "file_download");
message.setValue("filename", default_file);
sendMessage(message);
return std::vector<std::string>();
}
return std::vector<std::string>();
}
////////////////////////////////////////////////////////////////////////////////
//
const std::string MediaPluginCEF::onFileDialogCallback()
{
mPickedFile.clear();
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file");
message.setValueBoolean("blocking_request", true);
sendMessage(message);
return mPickedFile;
}
void MediaPluginCEF::onCursorChangedCallback(dullahan::ECursorType type)
{
std::string name = "";
@ -341,6 +386,8 @@ void MediaPluginCEF::onCursorChangedCallback(dullahan::ECursorType type)
sendMessage(message);
}
////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginCEF::authResponse(LLPluginMessage &message)
{
mAuthOK = message.getValueBoolean("ok");
@ -373,7 +420,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION;
message.setValueLLSD("versions", versions);
std::string plugin_version = "CEF plugin 1.1.3";
std::string plugin_version = "CEF plugin 1.1.412";
message.setValue("plugin_version", plugin_version);
sendMessage(message);
}
@ -439,17 +486,17 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
mCEFLib->setOnTitleChangeCallback(std::bind(&MediaPluginCEF::onTitleChangeCallback, this, std::placeholders::_1));
mCEFLib->setOnLoadStartCallback(std::bind(&MediaPluginCEF::onLoadStartCallback, this));
mCEFLib->setOnLoadEndCallback(std::bind(&MediaPluginCEF::onLoadEndCallback, this, std::placeholders::_1));
mCEFLib->setOnLoadErrorCallback(std::bind(&MediaPluginCEF::onLoadError, this, std::placeholders::_1, std::placeholders::_2));
mCEFLib->setOnAddressChangeCallback(std::bind(&MediaPluginCEF::onAddressChangeCallback, this, std::placeholders::_1));
mCEFLib->setOnNavigateURLCallback(std::bind(&MediaPluginCEF::onNavigateURLCallback, this, std::placeholders::_1, std::placeholders::_2));
mCEFLib->setOnOpenPopupCallback(std::bind(&MediaPluginCEF::onOpenPopupCallback, this, std::placeholders::_1, std::placeholders::_2));
mCEFLib->setOnHTTPAuthCallback(std::bind(&MediaPluginCEF::onHTTPAuthCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
mCEFLib->setOnFileDownloadCallback(std::bind(&MediaPluginCEF::onFileDownloadCallback, this, std::placeholders::_1));
mCEFLib->setOnFileDialogCallback(std::bind(&MediaPluginCEF::onFileDialogCallback, this));
mCEFLib->setOnFileDialogCallback(std::bind(&MediaPluginCEF::onFileDialog, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
mCEFLib->setOnCursorChangedCallback(std::bind(&MediaPluginCEF::onCursorChangedCallback, this, std::placeholders::_1));
mCEFLib->setOnRequestExitCallback(std::bind(&MediaPluginCEF::onRequestExitCallback, this));
dullahan::dullahan_settings settings;
settings.accept_language_list = mHostLanguage;
settings.background_color = 0xffffffff;
settings.background_color = 0xff282828;
settings.cache_enabled = true;
settings.cache_path = mCachePath;
settings.cookie_store_path = mCookiePath;
@ -468,6 +515,8 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
settings.plugins_enabled = mPluginsEnabled;
settings.user_agent_substring = mCEFLib->makeCompatibleUserAgentString(mUserAgentSubtring);
settings.webgl_enabled = true;
settings.log_file = mCefLogFile;
settings.log_verbose = mCefLogVerbose;
std::vector<std::string> custom_schemes(1, "secondlife");
mCEFLib->setCustomSchemes(custom_schemes);
@ -497,8 +546,11 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
{
std::string user_data_path_cache = message_in.getValue("cache_path");
std::string user_data_path_cookies = message_in.getValue("cookies_path");
mCachePath = user_data_path_cache + "cef_cache";
mCookiePath = user_data_path_cookies + "cef_cookies";
mCefLogFile = message_in.getValue("cef_log_file");
mCefLogVerbose = message_in.getValueBoolean("cef_verbose_log");
}
else if (message_name == "size_change")
{
@ -520,11 +572,11 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
mTextureWidth = texture_width;
mTextureHeight = texture_height;
mCEFLib->setSize(mWidth, mHeight);
};
};
mCEFLib->setSize(mWidth, mHeight);
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
message.setValue("name", name);
message.setValueS32("width", width);
@ -650,7 +702,14 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
}
if (message_name == "pick_file_response")
{
mPickedFile = message_in.getValue("file");
LLSD file_list_llsd = message_in.getValueLLSD("file_list");
LLSD::array_const_iterator iter = file_list_llsd.beginArray();
LLSD::array_const_iterator end = file_list_llsd.endArray();
for (; iter != end; ++iter)
{
mPickedFiles.push_back(((*iter).asString()));
}
}
if (message_name == "auth_response")
{
@ -697,6 +756,10 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
{
mCookiesEnabled = message_in.getValueBoolean("enable");
}
else if (message_name == "clear_cookies")
{
mCEFLib->deleteAllCookies();
}
else if (message_name == "set_user_agent")
{
mUserAgentSubtring = message_in.getValue("user_agent");

View File

@ -1 +1 @@
5.1.3
5.1.4

View File

@ -16155,6 +16155,17 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>CefVerboseLog</key>
<map>
<key>Comment</key>
<string>Enable/disable CEF verbose loggingk</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
</map>
</llsd>

View File

@ -1940,8 +1940,6 @@ bool LLAppViewer::cleanup()
LLAvatarIconIDCache::getInstance()->save();
LLViewerMedia::saveCookieFile();
// Stop the plugin read thread if it's running.
LLPluginProcessParent::setUseReadThread(false);
@ -3179,8 +3177,14 @@ LLSD LLAppViewer::getViewerInfo() const
cef_ver_codec << " / CEF: ";
cef_ver_codec << CEF_VERSION;
cef_ver_codec << " / Chrome: ";
cef_ver_codec << " / Chromium: ";
cef_ver_codec << CHROME_VERSION_MAJOR;
cef_ver_codec << ".";
cef_ver_codec << CHROME_VERSION_MINOR;
cef_ver_codec << ".";
cef_ver_codec << CHROME_VERSION_BUILD;
cef_ver_codec << ".";
cef_ver_codec << CHROME_VERSION_PATCH;
info["LIBCEF_VERSION"] = cef_ver_codec.str();
#else

View File

@ -1,4 +1,4 @@
/**
/**
* @file llfloaterfacebook.cpp
* @brief Implementation of llfloaterfacebook
* @author Gilbert@lindenlab.com
@ -41,7 +41,6 @@
#include "llresmgr.h" // LLLocale
#include "llsdserialize.h"
#include "llloadingindicator.h"
#include "llplugincookiestore.h"
#include "llslurl.h"
#include "lltrans.h"
#include "llsnapshotlivepreview.h"
@ -296,16 +295,11 @@ void LLFacebookStatusPanel::showConnectedLayout()
void LLFacebookStatusPanel::onConnect()
{
LLFacebookConnect::instance().checkConnectionToFacebook(true);
//Clear only the facebook browser cookies so that the facebook login screen appears
LLViewerMedia::getCookieStore()->removeCookiesByDomain(".facebook.com");
}
void LLFacebookStatusPanel::onDisconnect()
{
LLFacebookConnect::instance().disconnectFromFacebook();
LLViewerMedia::getCookieStore()->removeCookiesByDomain(".facebook.com");
}
void LLFacebookStatusPanel::clearAndClose()
@ -810,7 +804,7 @@ void LLFacebookCheckinPanel::sendCheckin()
LLAgentUI::buildSLURL(slurl);
std::string slurl_string = slurl.getSLURLString();
// Use a valid http:// URL if the scheme is secondlife://
// Use a valid http:// URL if the scheme is secondlife://
LLURI slurl_uri(slurl_string);
if (slurl_uri.scheme() == LLSLURL::SLURL_SECONDLIFE_SCHEME)
{

View File

@ -40,7 +40,6 @@
#include "llresmgr.h" // LLLocale
#include "llsdserialize.h"
#include "llloadingindicator.h"
#include "llplugincookiestore.h"
#include "llslurl.h"
#include "lltrans.h"
#include "llsnapshotlivepreview.h"
@ -660,16 +659,11 @@ void LLFlickrAccountPanel::showConnectedLayout()
void LLFlickrAccountPanel::onConnect()
{
LLFlickrConnect::instance().checkConnectionToFlickr(true);
//Clear only the flickr browser cookies so that the flickr login screen appears
LLViewerMedia::getCookieStore()->removeCookiesByDomain(".flickr.com");
}
void LLFlickrAccountPanel::onDisconnect()
{
LLFlickrConnect::instance().disconnectFromFlickr();
LLViewerMedia::getCookieStore()->removeCookiesByDomain(".flickr.com");
}
////////////////////////

View File

@ -41,7 +41,6 @@
#include "llresmgr.h" // LLLocale
#include "llsdserialize.h"
#include "llloadingindicator.h"
#include "llplugincookiestore.h"
#include "llslurl.h"
#include "lltrans.h"
#include "llsnapshotlivepreview.h"
@ -683,16 +682,11 @@ void LLTwitterAccountPanel::showConnectedLayout()
void LLTwitterAccountPanel::onConnect()
{
LLTwitterConnect::instance().checkConnectionToTwitter(true);
//Clear only the twitter browser cookies so that the twitter login screen appears
LLViewerMedia::getCookieStore()->removeCookiesByDomain(".twitter.com");
}
void LLTwitterAccountPanel::onDisconnect()
{
LLTwitterConnect::instance().disconnectFromTwitter();
LLViewerMedia::getCookieStore()->removeCookiesByDomain(".twitter.com");
}
////////////////////////

View File

@ -1022,7 +1022,7 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
// try as slurl first
if (!LLURLDispatcher::dispatch(url, "clicked", NULL, mTrusted))
{
LLWeb::loadURL(url, target, std::string());
LLWeb::loadURL(url, target, uuid);
}
// CP: removing this code because we no longer support popups so this breaks the flow.

View File

@ -965,9 +965,6 @@ bool idle_startup()
// Load Avatars icons cache
LLAvatarIconIDCache::getInstance()->load();
// Load media plugin cookies
LLViewerMedia::loadCookieFile();
LLRenderMuteList::getInstance()->loadFromFile();
//-------------------------------------------------

View File

@ -736,7 +736,7 @@ LLTextureView::~LLTextureView()
typedef std::pair<F32,LLViewerFetchedTexture*> decode_pair_t;
struct compare_decode_pair
{
bool operator()(const decode_pair_t& a, const decode_pair_t& b)
bool operator()(const decode_pair_t& a, const decode_pair_t& b) const
{
return a.first > b.first;
}

View File

@ -50,7 +50,6 @@
#include "llpanelprofile.h"
#include "llparcel.h"
#include "llpluginclassmedia.h"
#include "llplugincookiestore.h"
#include "llurldispatcher.h"
#include "lluuid.h"
#include "llversioninfo.h"
@ -154,7 +153,6 @@ LLViewerMediaObserver::~LLViewerMediaObserver()
}
LLPluginCookieStore *LLViewerMedia::sCookieStore = NULL;
LLURL LLViewerMedia::sOpenIDURL;
std::string LLViewerMedia::sOpenIDCookie;
LLPluginClassMedia* LLViewerMedia::sSpareBrowserMediaSource = NULL;
@ -169,8 +167,6 @@ static F64 sLowestLoadableImplInterest = 0.0f;
static bool sAnyMediaShowing = false;
static bool sAnyMediaPlaying = false;
static boost::signals2::connection sTeleportFinishConnection;
static std::string sUpdatedCookies;
static const char *PLUGIN_COOKIE_FILE_NAME = "plugin_cookies.txt";
//////////////////////////////////////////////////////////////////////////////////////////
static void add_media_impl(LLViewerMediaImpl* media)
@ -610,12 +606,6 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
sAnyMediaShowing = false;
sAnyMediaPlaying = false;
sUpdatedCookies = getCookieStore()->getChangedCookies();
if(!sUpdatedCookies.empty())
{
LL_DEBUGS() << "updated cookies will be sent to all loaded plugins: " << LL_ENDL;
LL_DEBUGS() << sUpdatedCookies << LL_ENDL;
}
impl_list::iterator iter = sViewerMediaImplList.begin();
impl_list::iterator end = sViewerMediaImplList.end();
@ -1059,64 +1049,6 @@ void LLViewerMedia::clearAllCookies()
pimpl->mMediaSource->clear_cookies();
}
}
// Clear all cookies from the cookie store
getCookieStore()->setAllCookies("");
// FIXME: this may not be sufficient, since the on-disk cookie file won't get written until some browser instance exits cleanly.
// It also won't clear cookies for other accounts, or for any account if we're not logged in, and won't do anything at all if there are no webkit plugins loaded.
// Until such time as we can centralize cookie storage, the following hack should cover these cases:
// HACK: Look for cookie files in all possible places and delete them.
// NOTE: this assumes knowledge of what happens inside the webkit plugin (it's what adds 'browser_profile' to the path and names the cookie file)
// Places that cookie files can be:
// <getOSUserAppDir>/browser_profile/cookies
// <getOSUserAppDir>/first_last/browser_profile/cookies (note that there may be any number of these!)
// <getOSUserAppDir>/first_last/plugin_cookies.txt (note that there may be any number of these!)
std::string base_dir = gDirUtilp->getOSUserAppDir() + gDirUtilp->getDirDelimiter();
std::string target;
std::string filename;
LL_DEBUGS() << "base dir = " << base_dir << LL_ENDL;
// The non-logged-in version is easy
target = base_dir;
target += "browser_profile";
target += gDirUtilp->getDirDelimiter();
target += "cookies";
LL_DEBUGS() << "target = " << target << LL_ENDL;
if(LLFile::isfile(target))
{
LLFile::remove(target);
}
// the hard part: iterate over all user directories and delete the cookie file from each one
LLDirIterator dir_iter(base_dir, "*_*");
while (dir_iter.next(filename))
{
target = gDirUtilp->add(base_dir, filename);
gDirUtilp->append(target, "browser_profile");
gDirUtilp->append(target, "cookies");
LL_DEBUGS() << "target = " << target << LL_ENDL;
if(LLFile::isfile(target))
{
LLFile::remove(target);
}
// Other accounts may have new-style cookie files too -- delete them as well
target = gDirUtilp->add(base_dir, filename);
gDirUtilp->append(target, PLUGIN_COOKIE_FILE_NAME);
LL_DEBUGS() << "target = " << target << LL_ENDL;
if(LLFile::isfile(target))
{
LLFile::remove(target);
}
}
// If we have an OpenID cookie, re-add it to the cookie store.
setOpenIDCookie(std::string());
}
/////////////////////////////////////////////////////////////////////////////////////////
@ -1145,7 +1077,7 @@ void LLViewerMedia::setCookiesEnabled(bool enabled)
LLViewerMediaImpl* pimpl = *iter;
if(pimpl->mMediaSource)
{
pimpl->mMediaSource->enable_cookies(enabled);
pimpl->mMediaSource->cookies_enabled(enabled);
}
}
}
@ -1170,127 +1102,7 @@ void LLViewerMedia::setProxyConfig(bool enable, const std::string &host, int por
/////////////////////////////////////////////////////////////////////////////////////////
// static
/////////////////////////////////////////////////////////////////////////////////////////
// static
LLPluginCookieStore *LLViewerMedia::getCookieStore()
{
if(sCookieStore == NULL)
{
sCookieStore = new LLPluginCookieStore;
}
return sCookieStore;
}
/////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerMedia::loadCookieFile()
{
// build filename for each user
std::string resolved_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PLUGIN_COOKIE_FILE_NAME);
if (resolved_filename.empty())
{
LL_INFOS() << "can't get path to plugin cookie file - probably not logged in yet." << LL_ENDL;
return;
}
// open the file for reading
llifstream file(resolved_filename.c_str());
if (!file.is_open())
{
LL_WARNS() << "can't load plugin cookies from file \"" << PLUGIN_COOKIE_FILE_NAME << "\"" << LL_ENDL;
return;
}
getCookieStore()->readAllCookies(file, true);
file.close();
// send the clear_cookies message to all loaded plugins
impl_list::iterator iter = sViewerMediaImplList.begin();
impl_list::iterator end = sViewerMediaImplList.end();
for (; iter != end; iter++)
{
LLViewerMediaImpl* pimpl = *iter;
if(pimpl->mMediaSource)
{
pimpl->mMediaSource->clear_cookies();
}
}
// If we have an OpenID cookie, re-add it to the cookie store.
setOpenIDCookie(std::string());
}
/////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerMedia::saveCookieFile()
{
// build filename for each user
std::string resolved_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PLUGIN_COOKIE_FILE_NAME);
if (resolved_filename.empty())
{
LL_INFOS() << "can't get path to plugin cookie file - probably not logged in yet." << LL_ENDL;
return;
}
// open a file for writing
llofstream file(resolved_filename.c_str());
if (!file.is_open())
{
LL_WARNS() << "can't open plugin cookie file \"" << PLUGIN_COOKIE_FILE_NAME << "\" for writing" << LL_ENDL;
return;
}
getCookieStore()->writePersistentCookies(file);
file.close();
}
/////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerMedia::addCookie(const std::string &name, const std::string &value, const std::string &domain, const LLDate &expires, const std::string &path, bool secure)
{
std::stringstream cookie;
cookie << name << "=" << LLPluginCookieStore::quoteString(value);
if(expires.notNull())
{
cookie << "; expires=" << expires.asRFC1123();
}
cookie << "; domain=" << domain;
cookie << "; path=" << path;
if(secure)
{
cookie << "; secure";
}
getCookieStore()->setCookies(cookie.str());
}
/////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerMedia::addSessionCookie(const std::string &name, const std::string &value, const std::string &domain, const std::string &path, bool secure)
{
// A session cookie just has a NULL date.
addCookie(name, value, domain, LLDate(), path, secure);
}
/////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerMedia::removeCookie(const std::string &name, const std::string &domain, const std::string &path )
{
// To remove a cookie, add one with the same name, domain, and path that expires in the past.
addCookie(name, "", domain, LLDate(LLDate::now().secondsSinceEpoch() - 1.0), path);
}
//// static
LLSD LLViewerMedia::getHeaders()
{
@ -1395,8 +1207,6 @@ void LLViewerMedia::getOpenIDCookieCoro(std::string url)
hostEnd = authority.size();
}
getCookieStore()->setCookiesFromHost(sOpenIDCookie, authority.substr(hostStart, hostEnd - hostStart));
if (url.length())
{
LLMediaCtrl* media_instance = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("destination_guide_contents");
@ -1434,7 +1244,6 @@ void LLViewerMedia::getOpenIDCookieCoro(std::string url)
httpHeaders->append(HTTP_OUT_HEADER_COOKIE, sOpenIDCookie);
httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, getCurrentUserAgent());
LL_DEBUGS("MediaAuth") << "Requesting " << url << LL_ENDL;
LL_DEBUGS("MediaAuth") << "sOpenIDCookie = [" << sOpenIDCookie << "]" << LL_ENDL;
@ -1459,13 +1268,9 @@ void LLViewerMedia::getOpenIDCookieCoro(std::string url)
const std::string& cookie = resultHeaders[HTTP_IN_HEADER_SET_COOKIE].asStringRef();
LL_DEBUGS("MediaAuth") << "cookie = " << cookie << LL_ENDL;
// *TODO: What about bad status codes? Does this destroy previous cookies?
LLViewerMedia::getCookieStore()->setCookiesFromHost(cookie, hostAuth);
// Set cookie for snapshot publishing.
std::string authCookie = cookie.substr(0, cookie.find(";")); // strip path
LLWebProfile::setAuthCookie(authCookie);
}
/////////////////////////////////////////////////////////////////////////////////////////
@ -1660,12 +1465,6 @@ void LLViewerMedia::cleanupClass()
delete sSpareBrowserMediaSource;
sSpareBrowserMediaSource = NULL;
}
if (sCookieStore != NULL)
{
delete sCookieStore;
sCookieStore = NULL;
}
}
//////////////////////////////////////////////////////////////////////////////////////////
@ -1898,6 +1697,8 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
std::string user_data_path_cookies = gDirUtilp->getOSUserAppDir();
user_data_path_cookies += gDirUtilp->getDirDelimiter();
std::string user_data_path_cef_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "cef_log.txt");
// Fix for EXT-5960 - make browser profile specific to user (cache, cookies etc.)
// If the linden username returned is blank, that can only mean we are
// at the login page displaying login Web page or Web browser test via Develop menu.
@ -1906,7 +1707,6 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
std::string linden_user_dir = gDirUtilp->getLindenUserDir();
if ( ! linden_user_dir.empty() )
{
// gDirUtilp->getLindenUserDir() is whole path, not just Linden name
user_data_path_cookies = linden_user_dir;
user_data_path_cookies += gDirUtilp->getDirDelimiter();
};
@ -1927,13 +1727,13 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
{
media_source = new LLPluginClassMedia(owner);
media_source->setSize(default_width, default_height);
media_source->setUserDataPath(user_data_path_cache, user_data_path_cookies);
media_source->setUserDataPath(user_data_path_cache, user_data_path_cookies, user_data_path_cef_log);
media_source->setLanguageCode(LLUI::getLanguage());
media_source->setZoomFactor(zoom_factor);
// collect 'cookies enabled' setting from prefs and send to embedded browser
bool cookies_enabled = gSavedSettings.getBOOL( "CookiesEnabled" );
media_source->enable_cookies( cookies_enabled || clean_browser);
media_source->cookies_enabled( cookies_enabled || clean_browser);
// collect 'plugins enabled' setting from prefs and send to embedded browser
bool plugins_enabled = gSavedSettings.getBOOL( "BrowserPluginsEnabled" );
@ -2040,17 +1840,6 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type)
media_source->clear_cache();
}
// TODO: Only send cookies to plugins that need them
// Ideally, the plugin should tell us whether it handles cookies or not -- either via the init response or through a separate message.
// Due to the ordering of messages, it's possible we wouldn't get that information back in time to send cookies before sending a navigate message,
// which could cause odd race conditions.
std::string all_cookies = LLViewerMedia::getCookieStore()->getAllCookies();
LL_DEBUGS() << "setting cookies: " << all_cookies << LL_ENDL;
if(!all_cookies.empty())
{
media_source->set_cookies(all_cookies);
}
mMediaSource = media_source;
mMediaSource->setDeleteOK(false) ;
updateVolume();
@ -2992,14 +2781,10 @@ void LLViewerMediaImpl::update()
updateVolume();
// TODO: this is updated every frame - is this bad?
updateJavascriptObject();
// If we didn't just create the impl, it may need to get cookie updates.
if(!sUpdatedCookies.empty())
{
// TODO: Only send cookies to plugins that need them
mMediaSource->set_cookies(sUpdatedCookies);
}
// Removing this as part of the post viewer64 media update
// Removed as not implemented in CEF embedded browser
// See MAINT-8194 for a more fuller description
// updateJavascriptObject();
}
@ -3489,22 +3274,40 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla
case LLViewerMediaObserver::MEDIA_EVENT_PICK_FILE_REQUEST:
{
// Display a file picker
std::string response;
LLFilePicker& picker = LLFilePicker::instance();
if (!picker.getOpenFile(LLFilePicker::FFLOAD_ALL))
std::vector<std::string> responses;
bool pick_multiple_files = plugin->getIsMultipleFilePick();
if (pick_multiple_files == false)
{
// The user didn't pick a file -- the empty response string will indicate this.
picker.getOpenFile(LLFilePicker::FFLOAD_ALL);
std::string filename = picker.getFirstFile();
responses.push_back(filename);
}
else
{
if (picker.getMultipleOpenFiles())
{
std::string filename = picker.getFirstFile();
response = picker.getFirstFile();
responses.push_back(filename);
plugin->sendPickFileResponse(response);
while (!filename.empty())
{
filename = picker.getNextFile();
if (!filename.empty())
{
responses.push_back(filename);
}
}
}
}
plugin->sendPickFileResponse(responses);
}
break;
case LLViewerMediaObserver::MEDIA_EVENT_AUTH_REQUEST:
{
LLNotification::Params auth_request_params;
@ -3572,13 +3375,6 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla
}
}
////////////////////////////////////////////////////////////////////////////////
// virtual
void LLViewerMediaImpl::handleCookieSet(LLPluginClassMedia* self, const std::string &cookie)
{
LLViewerMedia::getCookieStore()->setCookies(cookie);
}
////////////////////////////////////////////////////////////////////////////////
// virtual
void

View File

@ -50,7 +50,6 @@ class LLViewerMediaTexture;
class LLMediaEntry;
class LLVOVolume;
class LLMimeDiscoveryResponder;
class LLPluginCookieStore;
typedef LLPointer<LLViewerMediaImpl> viewer_media_t;
///////////////////////////////////////////////////////////////////////////////
@ -149,13 +148,6 @@ public:
// Set the proxy config for all loaded plugins
static void setProxyConfig(bool enable, const std::string &host, int port);
static LLPluginCookieStore *getCookieStore();
static void loadCookieFile();
static void saveCookieFile();
static void addCookie(const std::string &name, const std::string &value, const std::string &domain, const LLDate &expires, const std::string &path = std::string("/"), bool secure = false );
static void addSessionCookie(const std::string &name, const std::string &value, const std::string &domain, const std::string &path = std::string("/"), bool secure = false );
static void removeCookie(const std::string &name, const std::string &domain, const std::string &path = std::string("/") );
static void openIDSetup(const std::string &openid_url, const std::string &openid_token);
static void openIDCookieResponse(const std::string& url, const std::string &cookie);
@ -178,7 +170,6 @@ private:
static void openIDSetupCoro(std::string openidUrl, std::string openidToken);
static void getOpenIDCookieCoro(std::string url);
static LLPluginCookieStore *sCookieStore;
static LLURL sOpenIDURL;
static std::string sOpenIDCookie;
static LLPluginClassMedia* sSpareBrowserMediaSource;
@ -337,7 +328,6 @@ public:
// Inherited from LLPluginClassMediaOwner
/*virtual*/ void handleMediaEvent(LLPluginClassMedia* plugin, LLPluginClassMediaOwner::EMediaEvent);
/*virtual*/ void handleCookieSet(LLPluginClassMedia* self, const std::string &cookie);
// LLEditMenuHandler overrides
/*virtual*/ void cut();

View File

@ -440,7 +440,7 @@ public:
struct CompareRegionByLastUpdate
{
bool operator()(const LLViewerRegion* const& lhs, const LLViewerRegion* const& rhs)
bool operator()(const LLViewerRegion* const& lhs, const LLViewerRegion* const& rhs) const
{
S32 lpa = lhs->getLastUpdate();
S32 rpa = rhs->getLastUpdate();

View File

@ -59,7 +59,7 @@ public:
struct CompareVOCacheEntry
{
bool operator()(const LLVOCacheEntry* const& lhs, const LLVOCacheEntry* const& rhs)
bool operator()(const LLVOCacheEntry* const& lhs, const LLVOCacheEntry* const& rhs) const
{
F32 lpa = lhs->getSceneContribution();
F32 rpa = rhs->getSceneContribution();

View File

@ -31,7 +31,6 @@
// libs
#include "llbufferstream.h"
#include "llimagepng.h"
#include "llplugincookiestore.h"
#include "llsdserialize.h"

View File

@ -8,14 +8,14 @@
help_topic="floater_about"
save_rect="true"
title="ABOUT [CAPITALIZED_APP_NAME]"
width="470">
width="500">
<tab_container
follows="all"
top="25"
left="10"
height="405"
width="450"
width="480"
name="about_tab"
tab_position="top">
<panel
@ -33,7 +33,7 @@
max_length="65536"
name="support_editor"
top="5"
width="435"
width="465"
word_wrap="true" />
<button
follows="left|top"
@ -56,7 +56,7 @@
left="5"
name="linden_intro"
top="10"
width="435"
width="465"
wrap="true">
Second Life is brought to you by the Lindens,
with open source contributions from:
@ -71,7 +71,7 @@ with open source contributions from:
max_length="65536"
name="contrib_names"
top_pad="10"
width="435"
width="465"
word_wrap="true">
Dummy Name replaced at run time
</text_editor>
@ -91,7 +91,7 @@ Dummy Name replaced at run time
max_length="65536"
name="licenses_editor"
top="5"
width="435"
width="465"
word_wrap="true">
3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion
APR Copyright (C) 2011 The Apache Software Foundation

View File

@ -178,108 +178,7 @@
width="22">
<button.commit_callback
function="WebContent.TestURL"
parameter="https://callum-linden.s3.amazonaws.com/ceftests.html"/>
</button>
<button
image_overlay="Video_URL_Off"
image_disabled="PushButton_Disabled"
image_disabled_selected="PushButton_Disabled"
image_selected="PushButton_Selected"
image_unselected="PushButton_Off"
chrome="true"
tool_tip="MPEG4 Video Test"
enabled="true"
follows="left|top"
height="22"
layout="topleft"
left="27"
name="VLC Plugin Test"
top="0"
width="22">
<button.commit_callback
function="WebContent.TestURL"
parameter="https://callum-linden.s3.amazonaws.com/sample_media/ss.mp4"/>
</button>
<button
image_overlay="Video_URL_Off"
image_disabled="PushButton_Disabled"
image_disabled_selected="PushButton_Disabled"
image_selected="PushButton_Selected"
image_unselected="PushButton_Off"
chrome="true"
tool_tip="MKV Video Test"
enabled="true"
follows="left|top"
height="22"
layout="topleft"
left="51"
name="VLC Plugin Test"
top="0"
width="22">
<button.commit_callback
function="WebContent.TestURL"
parameter="https://callum-linden.s3.amazonaws.com/sample_media/jellyfish.mkv"/>
</button>
<button
image_overlay="Video_URL_Off"
image_disabled="PushButton_Disabled"
image_disabled_selected="PushButton_Disabled"
image_selected="PushButton_Selected"
image_unselected="PushButton_Off"
chrome="true"
tool_tip="WebM Video Test"
enabled="true"
follows="left|top"
height="22"
layout="topleft"
left="75"
name="VLC Plugin Test"
top="0"
width="22">
<button.commit_callback
function="WebContent.TestURL"
parameter="https://callum-linden.s3.amazonaws.com/sample_media/jumprope.webm"/>
</button>
<button
image_overlay="Video_URL_Off"
image_disabled="PushButton_Disabled"
image_disabled_selected="PushButton_Disabled"
image_selected="PushButton_Selected"
image_unselected="PushButton_Off"
chrome="true"
tool_tip="MP3 audio Test"
enabled="true"
follows="left|top"
height="22"
layout="topleft"
left="99"
name="VLC Plugin Test"
top="0"
width="22">
<button.commit_callback
function="WebContent.TestURL"
parameter="https://callum-linden.s3.amazonaws.com/alegria.mp3"/>
</button>
<button
image_overlay="Video_URL_Off"
image_disabled="PushButton_Disabled"
image_disabled_selected="PushButton_Disabled"
image_selected="PushButton_Selected"
image_unselected="PushButton_Off"
chrome="true"
tool_tip="FLV Test"
enabled="true"
follows="left|top"
height="22"
layout="topleft"
left="123"
name="VLC Plugin Test"
top="0"
width="22">
<button.commit_callback
function="WebContent.TestURL"
parameter="https://callum-linden.s3.amazonaws.com/sample_media/vandal.flv"/>
parameter="https://sl-viewer-media-system.s3.amazonaws.com/index.html"/>
</button>
</layout_panel>
<layout_panel

View File

@ -245,7 +245,7 @@
name="Media Browser">
<menu_item_call.on_click
function="Advanced.WebContentTest"
parameter="http://google.com"/>
parameter="http://duckduckgo.com"/>
</menu_item_call>
<menu
create_jump_keys="true"

View File

@ -3173,7 +3173,7 @@
shortcut="control|alt|shift|Z">
<menu_item_call.on_click
function="Advanced.WebContentTest"
parameter="http://google.com"/>
parameter="http://duckduckgo.com"/>
</menu_item_call>
<menu_item_call
label="FB Connect Test"

View File

@ -19,7 +19,7 @@
follows="left|top"
height="23"
label="Clear History"
tool_tip="Clear login image, last location, teleport history, web, and texture cache"
tool_tip="Clear login image, last location, teleport history, web and texture cache"
layout="topleft"
left="30"
name="clear_cache"

View File

@ -106,38 +106,6 @@
width="300">
Web:
</text>
<!-- <radio_group
control_name="UseExternalBrowser"
draw_border="false"
follows="top|left"
height="40"
layout="topleft"
left_delta="50"
name="use_external_browser"
top_pad="-2"
width="480">
<radio_item
height="20"
label="Use my browser (IE, Firefox, Safari)"
layout="topleft"
left_delta="0"
name="external"
value="true"
top="0"
tool_tip="Use the default system web browser for help, web links, etc. Not recommended if running full screen."
width="480" />
<radio_item
height="20"
label="Use built-in browser"
layout="topleft"
left="0"
name="internal"
value=""
tool_tip="Use the built-in web browser for help, web links, etc. This browser opens as a new window inside [APP_NAME]."
top_delta="20"
width="480" />
</radio_group> -->
<radio_group
control_name="PreferredBrowserBehavior"
follows="left|top"
@ -149,7 +117,7 @@
width="480">
<radio_item
height="20"
label="Use my browser (Chrome, Firefox, IE) for all links"
label="Use the default system browser for all links"
layout="topleft"
left="0"
name="internal"
@ -159,17 +127,17 @@
width="480" />
<radio_item
height="20"
label="Use built-in browser for Second Life links only"
label="Use the built-in browser for Second Life links only"
layout="topleft"
left_delta="0"
name="external"
value="1"
tool_tip="Use the default system web browser for help, web links, etc. Builtin browser will be used only for LindenLab/SecondLife links."
tool_tip="Use the default system web browser for help, web links, etc. The built-in browser will be used only for LindenLab/Second Life links."
top_delta="20"
width="480" />
<radio_item
height="20"
label="Use built-in browser for all links"
label="Use the built-in browser for all links"
layout="topleft"
left="0"
name="external_all"
@ -193,22 +161,6 @@
radio_style="false"
width="400"
top_pad="5"/>
<check_box
top_delta="4"
enabled="true"
follows="left|top"
height="14"
initial_value="true"
control_name="CookiesEnabled"
label="Accept cookies"
left_delta="0"
mouse_opaque="true"
name="cookies_enabled"
radio_style="false"
width="400"
top_pad="5"/>
<check_box
top_delta="4"
enabled="true"