Merge Firestorm LGPL Lynx

master
Ansariel 2018-04-12 22:58:42 +02:00
commit 37b8d0a10e
41 changed files with 250 additions and 1591 deletions

View File

@ -572,3 +572,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

@ -756,9 +756,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>
@ -792,9 +792,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>
@ -804,16 +804,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>
@ -3630,9 +3630,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>
@ -3666,9 +3666,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>
@ -3678,16 +3678,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

@ -157,11 +157,9 @@ if (LINUX)
if ( ${FORTIFY_SOURCE_RES} EQUAL 0 )
add_definitions(-D_FORTIFY_SOURCE=2)
endif()
set(CMAKE_CXX_FLAGS "-Wno-deprecated -Wno-unused-but-set-variable -Wno-unused-variable -Wno-placement-new ${CMAKE_CXX_FLAGS}")
# gcc 4.3 and above don't like the LL boost and also
# cause warnings due to our use of deprecated headers
add_definitions(-Wno-parentheses)
add_definitions(
-D_REENTRANT
@ -176,18 +174,9 @@ if (LINUX)
-pthread
)
# <FS:ND> Enable C++11 support + gnu extensions
add_definitions(-std=gnu++11)
# </FS:ND>
# <FS:ND> Enable old C++ ABI
add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)
# </FS:ND>
# force this platform to accept TOS via external browser <FS:ND> No, do not.
# add_definitions(-DEXTERNAL_TOS)
add_definitions(-DAPPID=secondlife)
add_compile_options(-fvisibility=hidden)
# don't catch SIGCHLD in our base application class for the viewer - some of

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;
@ -794,15 +797,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);
}
@ -838,11 +848,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);
}
@ -1102,6 +1118,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")
@ -1163,7 +1180,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")
@ -1178,13 +1200,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);
@ -1299,14 +1314,7 @@ void LLPluginClassMedia::clear_cookies()
sendMessage(message);
}
void LLPluginClassMedia::set_cookies(const std::string &cookies)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_cookies");
message.setValue("cookies", cookies);
sendMessage(message);
}
void LLPluginClassMedia::enable_cookies(bool enable)
void LLPluginClassMedia::cookies_enabled(bool enable)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "cookies_enabled");
message.setValueBoolean("enable", enable);

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

@ -350,7 +350,7 @@ LLUrlEntryInvalidSLURL::LLUrlEntryInvalidSLURL()
{
// <FS:Ansariel> Inworldz special
//mPattern = boost::regex("(http://(maps.secondlife.com|slurl.com)/secondlife/|secondlife://(/app/(worldmap|teleport)/)?)[^ /]+(/-?[0-9]+){1,3}(/?(\\?title|\\?img|\\?msg)=\\S*)?/?",
mPattern = boost::regex("(http://(maps.secondlife.com|slurl.com)/secondlife/|(secondlife|inworldz|iw)://(/app/(worldmap|teleport)/)?)[^ /]+(/-?[0-9]+){1,3}(/?(\\?title|\\?img|\\?msg)=\\S*)?/?",
mPattern = boost::regex("(https?://(maps.secondlife.com|slurl.com)/secondlife/|(secondlife|inworldz|iw)://(/app/(worldmap|teleport)/)?)[^ /]+(/-?[0-9]+){1,3}(/?(\\?title|\\?img|\\?msg)=\\S*)?/?",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_http.xml";
mTooltip = LLTrans::getString("TooltipHttpUrl");
@ -437,7 +437,7 @@ bool LLUrlEntryInvalidSLURL::isSLURLvalid(const std::string &url) const
LLUrlEntrySLURL::LLUrlEntrySLURL()
{
// see http://slurl.com/about.php for details on the SLURL format
mPattern = boost::regex("http://(maps.secondlife.com|slurl.com)/secondlife/[^ /]+(/\\d+){0,3}(/?(\\?title|\\?img|\\?msg)=\\S*)?/?",
mPattern = boost::regex("https?://(maps.secondlife.com|slurl.com)/secondlife/[^ /]+(/\\d+){0,3}(/?(\\?title|\\?img|\\?msg)=\\S*)?/?",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_slurl.xml";
mTooltip = LLTrans::getString("TooltipSLURL");

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);
}
}
@ -210,6 +219,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()
@ -243,12 +267,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);
}
@ -287,30 +310,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 = "";
@ -343,6 +388,8 @@ void MediaPluginCEF::onCursorChangedCallback(dullahan::ECursorType type)
sendMessage(message);
}
////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginCEF::authResponse(LLPluginMessage &message)
{
mAuthOK = message.getValueBoolean("ok");
@ -375,7 +422,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);
}
@ -441,17 +488,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;
@ -470,6 +517,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);
@ -499,8 +548,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")
{
@ -522,11 +574,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);
@ -653,7 +705,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")
{
@ -700,6 +759,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

@ -21042,6 +21042,17 @@ Change of this parameter will affect the layout of buttons in notification toast
<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>
<key>FSShowServerVersionChangeNotice</key>
<map>
<key>Comment</key>

View File

@ -2318,8 +2318,6 @@ bool LLAppViewer::cleanup()
LLAvatarIconIDCache::getInstance()->save();
LLViewerMedia::saveCookieFile();
// Stop the plugin read thread if it's running.
LLPluginProcessParent::setUseReadThread(false);
@ -3832,8 +3830,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"
@ -303,16 +302,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()
@ -914,7 +908,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"
@ -889,16 +888,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

@ -560,7 +560,6 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
mCommitCallbackRegistrar.add("Pref.BrowseCrashLogs", boost::bind(&LLFloaterPreference::onClickBrowseCrashLogs, this));
mCommitCallbackRegistrar.add("Pref.BrowseSettingsDir", boost::bind(&LLFloaterPreference::onClickBrowseSettingsDir, this));
mCommitCallbackRegistrar.add("Pref.BrowseLogPath", boost::bind(&LLFloaterPreference::onClickBrowseChatLogDir, this));
mCommitCallbackRegistrar.add("Pref.Cookies", boost::bind(&LLFloaterPreference::onClickCookies, this));
mCommitCallbackRegistrar.add("Pref.Javascript", boost::bind(&LLFloaterPreference::onClickJavascript, this));
//[FIX FIRE-2765 : SJ] Making sure Reset button resets works
mCommitCallbackRegistrar.add("Pref.ResetLogPath", boost::bind(&LLFloaterPreference::onClickResetLogPath, this));
@ -1849,16 +1848,13 @@ void LLFloaterPreference::setPreprocInclude()
}
}
//[FIX JIRA-1971 : SJ] Show an notify when Cookies setting change
void LLFloaterPreference::onClickCookies()
{
LLNotificationsUtil::add("DisableCookiesBreaksSearch");
}
//[FIX JIRA-1971 : SJ] Show an notify when Javascript setting change
void LLFloaterPreference::onClickJavascript()
{
LLNotificationsUtil::add("DisableJavascriptBreaksSearch");
if (!gSavedSettings.getBOOL("BrowserJavascriptEnabled"))
{
LLNotificationsUtil::add("DisableJavascriptBreaksSearch");
}
}
/*

View File

@ -184,7 +184,6 @@ public:
void onClickBrowseChatLogDir();
void onClickResetCache();
void onClickClearCache(); // AO: was protected, moved to public
void onClickCookies();
void onClickJavascript();
void onClickBrowseSettingsDir();
void onClickSkin(LLUICtrl* ctrl,const LLSD& userdata);

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"
@ -782,16 +781,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

@ -1060,7 +1060,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

@ -1090,7 +1090,7 @@ void LLPanelMainInventory::updateItemcountText()
}
mCounterCtrl->setValue(text);
mCounterCtrl->setToolTip(text);
//mCounterCtrl->setToolTip(text); // <FS:Ansariel> Include folders in inventory count
}
void LLPanelMainInventory::onFocusReceived()

View File

@ -1517,9 +1517,6 @@ bool idle_startup()
// Load Avatars icons cache
LLAvatarIconIDCache::getInstance()->load();
// Load media plugin cookies
LLViewerMedia::loadCookieFile();
// <FS:Ansariel> [FS Persisted Avatar Render Settings]
//LLRenderMuteList::getInstance()->loadFromFile();

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)
@ -614,12 +610,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();
@ -1087,64 +1077,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());
}
/////////////////////////////////////////////////////////////////////////////////////////
@ -1173,7 +1105,7 @@ void LLViewerMedia::setCookiesEnabled(bool enabled)
LLViewerMediaImpl* pimpl = *iter;
if(pimpl->mMediaSource)
{
pimpl->mMediaSource->enable_cookies(enabled);
pimpl->mMediaSource->cookies_enabled(enabled);
}
}
}
@ -1198,127 +1130,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()
{
@ -1423,8 +1235,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");
@ -1462,7 +1272,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;
@ -1487,13 +1296,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);
}
/////////////////////////////////////////////////////////////////////////////////////////
@ -1688,12 +1493,6 @@ void LLViewerMedia::cleanupClass()
delete sSpareBrowserMediaSource;
sSpareBrowserMediaSource = NULL;
}
if (sCookieStore != NULL)
{
delete sCookieStore;
sCookieStore = NULL;
}
}
//////////////////////////////////////////////////////////////////////////////////////////
@ -1943,6 +1742,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.
@ -1951,7 +1752,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();
};
@ -1972,13 +1772,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" );
@ -2085,17 +1885,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();
@ -3055,14 +2844,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();
}
@ -3555,22 +3340,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;
@ -3638,13 +3441,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

@ -2829,6 +2829,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
gSkinnedObjectSimpleWaterProgram.mFeatures.hasObjectSkinning = true;
gSkinnedObjectSimpleWaterProgram.mFeatures.disableTextureIndex = true;
gSkinnedObjectSimpleWaterProgram.mFeatures.hasAlphaMask = true;
gSkinnedObjectSimpleWaterProgram.mShaderFiles.clear();
gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));

View File

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

View File

@ -12,11 +12,6 @@
</layout_panel>
<layout_panel name="debug_controls">
<button name="web_test_home_page" tool_tip="Webtests Homepage"/>
<button name="VLC Plugin Test MPEG4" tool_tip="MPEG4-Videotest"/>
<button name="VLC Plugin Test MKV" tool_tip="MKV-Videotest"/>
<button name="VLC Plugin Test WebM" tool_tip="WebM-Videotest"/>
<button name="VLC Plugin Test MP3" tool_tip="MP3-Audiotest"/>
<button name="VLC Plugin Test FLV" tool_tip="FLV-Test"/>
</layout_panel>
<layout_panel name="external_controls">
<text name="plugin_fail_text">

View File

@ -597,6 +597,9 @@ Sind Sie sicher, dass Sie fortfahren wollen?
<notification name="CacheWillClear">
Der Cache wird nach einem Neustart von [APP_NAME] geleert.
</notification>
<notification name="DisableJavascriptBreaksSearch">
Wenn Sie Javascript deaktivieren wird die Suchfunktion nicht korrekt funktionieren und Sie werden sie nicht benutzen können.
</notification>
<notification name="CacheWillBeMoved">
Der Cache wird nach einem Neustart von [APP_NAME] verschoben.
Hinweis: Der Cache wird dabei gelöscht/geleert.

View File

@ -23,7 +23,7 @@
Web-Browser:
</text>
<radio_group name="preferred_browser_behavior">
<radio_item label="Meinen Browser (IE, Firefox, Safari) für alle Links verwenden" name="new_external" tool_tip="Standard Webbrowser des Systems verwenden, um die Hilfe, Weblinks usw. anzuzeigen. Bei Vollbildmodus nicht empfohlen."/>
<radio_item label="Standard-Webbrowser des Systems für alle Links verwenden" name="new_external" tool_tip="Standard-Webbrowser des Systems verwenden, um die Hilfe, Weblinks usw. anzuzeigen. Bei Vollbildmodus nicht empfohlen."/>
<radio_item label="Integrierten Browser nur für Second-Life-Links verwenden" name="new_internal" tool_tip="Integrierten Webbrowser verwenden, um die Hilfe, Weblinks usw. anzuzeigen. Dieser Browser öffnet als neues Fenster innerhalb von [APP_NAME]."/>
<radio_item label="Integrierten Browser für alle Links verwenden" name="new_internal_all" tool_tip="Integrierten Webbrowser verwenden, um die Hilfe, Weblinks usw. anzuzeigen. Dieser Browser öffnet als neues Fenster innerhalb von [APP_NAME]."/>
</radio_group>
@ -38,7 +38,6 @@
</combo_box>
<button label="Webbrowser-Cache löschen" name="ClearWebBrowserCache" width="160"/>
<check_box label="Plugins aktivieren" name="browser_plugins_enabled"/>
<check_box label="Cookies annehmen" name="cookies_enabled"/>
<check_box label="Javascript aktivieren" name="browser_javascript_enabled"/>
<check_box label="Medienbrowser-Popups aktivieren" name="media_popup_enabled"/>
<button label="Proxy-Einstellungen ändern" label_selected="Proxy-Einstellungen ändern" name="set_proxy"/>

View File

@ -8,14 +8,14 @@
help_topic="floater_about"
save_rect="true"
title="About [APP_NAME]"
width="470">
width="500">
<tab_container
follows="all"
top="20"
left="7"
height="572"
width="456"
width="486"
name="about_tab"
tab_position="top">
<panel
@ -46,7 +46,7 @@ http://www.firestormviewer.org
max_length="65536"
name="support_editor"
top_pad="5"
width="444"
width="474"
word_wrap="true" />
<button
follows="left|top"
@ -69,7 +69,7 @@ http://www.firestormviewer.org
left="4"
name="linden_intro"
top="16"
width="444"
width="474"
wrap="true">
Firestorm would not be possible without the decision from Linden Lab to make their Second Life viewer source code available.
@ -85,7 +85,7 @@ with open source contributions from:
max_length="65536"
name="contrib_names"
top_pad="5"
width="446"
width="476"
word_wrap="true">
Dummy Name replaced at run time
</text_editor>
@ -122,7 +122,7 @@ Dummy Name replaced at run time
left="5"
name="firestorm_intro"
top="0"
width="420"
width="450"
wrap="true">
Firestorm is a community development project to improve the SecondLife(tm) Viewer experience. We package contributions from various community developers along with code from Linden Lab and ourselves to bring you a quality, feature-rich viewer experience backed up by a large volunteer support team. Firestorm is brought to you by The Phoenix Firestorm Project, Inc., a non-profit organization.
@ -138,7 +138,7 @@ The Firestorm Development Team:
max_length="65536"
name="firestorm_names"
top_pad="4"
width="420"
width="450"
wrap="true">
Ansariel Hiller, ArminWeatherHax, Arrehn Oberlander, Beq Janus, Cinder Roxley, Holy Gavenkrantz, Jessica Lyon, Kadah Coba, Kitty Barnett, Liny Odell, LordGregGreg Back, Mobius Ryba, Nicky Dasmijn, PanteraPolnocy, Selo Jacobus, Tankmaster Finesmith, Techwolf Lupindo, Tonya Souther, Tozh Taurog, Vortex Saito, WoLf Loonie, Wolfspirit Magic and Zi Ree.
</text>
@ -149,7 +149,7 @@ Ansariel Hiller, ArminWeatherHax, Arrehn Oberlander, Beq Janus, Cinder Roxley, H
left="5"
name="fs_contrib_intro"
top_pad="8"
width="420"
width="450"
wrap="true">
Additional code generously contributed to Firestorm by:
</text>
@ -163,7 +163,7 @@ Additional code generously contributed to Firestorm by:
max_length="65536"
name="fs_contrib_names"
top_pad="4"
width="420"
width="450"
wrap="true">
Albatroz Hird, Alexie Birman, Andromeda Rage, Armin Weatherwax, Beq Janus, Casper Warden, Chalice Yao, Cron Stardust, Damian Zhaoying, Dan Threebeards, Dawa Gurbux, Drake Arconis, Felyza Wishbringer, f0rbidden, Fractured Crystal, Geenz Spad, Gibson Firehawk, Hitomi Tiponi, Inusaito Sayori, Katharine Berry, Kittin Ninetails, Kool Koolhoven, Lance Corrimal, Latif Khalifa, Magne Metaverse LLC, Magus Freston, Manami Hokkigai, MartinRJ Fayray, McCabe Maxstead, Melancholy Lemon, Melysmile, Mimika Oh, Mister Acacia, Mysty Saunders, Nagi Michinaga, Name Short, nhede Core, NiranV Dean, Nogardrevlis Lectar, Paladin Forzane, paperwork, Peyton Menges, programmtest, Qwerty Venom, Revolution Smythe, Sahkolihaa Contepomi, sal Kaligawa, Samm Florian, Satomi Ahn, Sei Lisa, Sempervirens Oddfellow, Shin Wasp, Shyotl Kuhr, Sione Lomu, Skills Hak, StarlightShining, Sunset Faulkes, Thickbrick Sleaford, Vaalith Jinn, Vincent Sylvester, Whirly Fizzle, Xenhat Liamano, Zwagoth Klaar and others.
</text>
@ -174,7 +174,7 @@ Albatroz Hird, Alexie Birman, Andromeda Rage, Armin Weatherwax, Beq Janus, Caspe
left="5"
name="fs_support_intro"
top_pad="8"
width="420"
width="450"
wrap="true">
Special thanks to our Firestorm Support Team, wiki editors, educators, and translators:
</text>
@ -188,7 +188,7 @@ Special thanks to our Firestorm Support Team, wiki editors, educators, and trans
max_length="65536"
name="fs_trans_names"
top_pad="4"
width="420"
width="450"
word_wrap="true">
Afrika Burton, Albatroz Hird, Alexru Resident, alison Seesaw, AnaLucia Loon, Angell Airy, Annuccia Resident, Annuccia Vuckovic, Anubi Alter, Atthosz Amiot, Ayelin Ethaniel, Basement Desade, Bia Scribe, Bluezy Bleac, Clarke2, Christy Mansbridge, Chymy India, Cordoba Cluny, Damian Zhaoying, DARK Mirabella, Emmanuella Checchinato, Ed Merryman, Eressea Karsin, Erick Gregan, F0RBIDDEN, Fabry String, Fetish3d, Flandria Connolly, Foksy, Franklyn Watanabe, FreeSpirit Simmering, Gee McAuley, Greatfox Snowpaw, Gweneth Lange, Hatake Kohime, Hiroshi Kumaki, Hope Dreier, Jodi Nikolaidis, JogiTE Clip, Kool Koolhoven, Kosmox Voom, Lachrimo Skytower, Lalwende Leakey, Landaree Levee, Lassie, Lette Ponnier, Lina Pussycat, Lyn Mimistrobell, Marianne Qunhua, Marybeth Oceanlane, Mel Hinarada, Mickeala Praga, Miller Thor, Miro Collas, Mister Acacia, Morgause Whiteberry, Mysty Saunders, Nano Bouscario, narcisssia McMahon, Natem Andel, Nicoletta Schnute, Nisa Maverick, NogarDrevlis Lectar, Norton Burns, PanteraPolnocy, Peewee Musytari, Pisano Smit, PixelProphet Lane, Pol Xaron, Poledra Behemoth, Programmtest, Rander Teskat, Ricky Munz, Riku Highfield, RINOBIT Footman, Robert0 Siamendes, Roth Grut, Sabah Back, SaHaRa Connor, Selene Gregoire, Selo Jacobus, silvanaf Demina, Sniper Siemans, Spartaco Zemenis, Spino Forcella, Srilania Svoboda, Sunset Faulkes, Tanja Levenque, TankMaster Finesmith, Tarlyn Dagger, Thea Brianna, Toy Wylie, Whirly Fizzle, Willow Wilder, Wolfspirit Magic and XLR8RRICK Hudson.
</text>
@ -199,7 +199,7 @@ Afrika Burton, Albatroz Hird, Alexru Resident, alison Seesaw, AnaLucia Loon, Ang
left="5"
name="fs_art_intro"
top_pad="8"
width="420"
width="450"
wrap="true">
Firestorm includes Starlight, modified for Firestorm. It is provided by residents for residents, with the intention of providing an alternative, brighter, and hopefully easier to use interface. For further details see &lt;nolink&gt;https://wiki.secondlife.com/wiki/Viewer_Skins/Starlight&lt;/nolink&gt;.
@ -215,7 +215,7 @@ UI Artists and Designers:
max_length="65536"
name="fs_artists_names"
top_pad="4"
width="420"
width="450"
wrap="true">
Adam Frisby, Alexandrea Fride, DarkAgent Baphomet, David Rowe, Digital Scribe, Hitomi Tiponi, Hugh Helendale, KirstenLee Cinquetti, Mobius Ryba, Nadin, Naomah Beaumont, Paladin Forzane, psi Merlin, samm florian, Sammie Benoir, Tommi Waydelich and Vincent Nacon.
</text>
@ -237,7 +237,7 @@ Adam Frisby, Alexandrea Fride, DarkAgent Baphomet, David Rowe, Digital Scribe, H
max_length="65536"
name="licenses_editor"
top="16"
width="444"
width="474"
word_wrap="true">
3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion
APR Copyright (C) 2011 The Apache Software Foundation

View File

@ -180,108 +180,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 MPEG4"
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 MKV"
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 WebM"
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 MP3"
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 FLV"
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

@ -281,7 +281,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

@ -4283,7 +4283,7 @@
shortcut="control|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

@ -1541,13 +1541,6 @@ Cache will be cleared after restarting [APP_NAME].
<notification
icon="alertmodal.tga"
name="DisableCookiesBreaksSearch"
type="alertmodal">
If you disable cookies, the search function will not work properly, and you will not be able to use it.
</notification>
<notification
icon="alertmodal.tga"
name="DisableJavascriptBreaksSearch"
type="alertmodal">
If you disable Javascript, the search function will not work properly, and you will not be able to use it.

View File

@ -51,7 +51,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="15"
name="clear_cache"

View File

@ -215,7 +215,6 @@
width="400">
Web browser:
</text>
<radio_group
control_name="PreferredBrowserBehavior"
follows="left|top"
@ -227,7 +226,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="new_external"
@ -237,18 +236,18 @@
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="new_internal"
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/SecondLife links."
top_delta="15"
width="480" />
<radio_item
top_delta="15"
height="20"
label="Use built-in browser for all links"
label="Use the built-in browser for all links"
layout="topleft"
left="0"
name="new_internal_all"
@ -323,23 +322,6 @@
width="200"
top_pad="5"/>
<check_box
enabled="true"
follows="left|top"
height="16"
initial_value="true"
control_name="CookiesEnabled"
label="Accept cookies"
left_delta="0"
mouse_opaque="true"
name="cookies_enabled"
radio_style="false"
width="200"
top_pad="5">
<check_box.commit_callback
function="Pref.Cookies" />
</check_box>
<check_box
enabled="true"
follows="left|top"

View File

@ -542,9 +542,6 @@ No se reembolsarán las cuotas pagadas.
<notification name="CacheWillClear">
La caché se limpiará cuando reinicies [APP_NAME].
</notification>
<notification name="DisableCookiesBreaksSearch">
Si desactivas las cookies, la función de búsqueda no funcionará correctamente y no podrás usarla.
</notification>
<notification name="DisableJavascriptBreaksSearch">
Si desactivas Javascript, la función de búsqueda no funcionará correctamente y no podrás usarla.
</notification>

View File

@ -616,9 +616,6 @@ L$ が不足しているのでこのグループに参加することができ
<notification name="CacheWillClear">
[APP_NAME] を再起動後にキャッシュがクリアされます。
</notification>
<notification name="DisableCookiesBreaksSearch">
クッキーを無効にすると、検索機能が正しく働かず、検索を使用できなくなります。
</notification>
<notification name="DisableJavascriptBreaksSearch">
Javascript を無効にすると、検索機能が正しく働かず、検索を使用できなくなります。
</notification>

View File

@ -510,9 +510,6 @@ Czy na pewno chcesz kontynuować?
<notification name="CacheWillClear">
Bufor danych zostanie wyczyszczony po restarcie aplikacji [APP_NAME].
</notification>
<notification name="DisableCookiesBreaksSearch">
Jeśli wyłączysz ciasteczka, to wyszukiwarka przestanie działać.
</notification>
<notification name="DisableJavascriptBreaksSearch">
Jeśli wyłączysz Javascript, to wyszukiwarka przestanie działać.
</notification>

View File

@ -549,9 +549,6 @@
<notification name="CacheWillClear">
Кэш будет очищен после перезапуска [APP_NAME].
</notification>
<notification name="DisableCookiesBreaksSearch">
Если вы отключите Cookies, функции поиска не будут работать должным образом и вы не сможете его использовать.
</notification>
<notification name="DisableJavascriptBreaksSearch">
Если вы отключите Javascript, функции поиска не будут работать должным образом и вы не сможете его использовать.
</notification>