Merge viewer-media-update

Wed, 14 Feb 2018 21:56:53 +0100

author
Ansariel
date
Wed, 14 Feb 2018 21:56:53 +0100
changeset 55073
05942a2562e7
parent 54830
ffdea25134fb
parent 55072
84ada9b4a425
child 55074
0908f0d606f9

Merge viewer-media-update

autobuild.xml file | annotate | diff | revisions
indra/llplugin/CMakeLists.txt file | annotate | diff | revisions
indra/llplugin/llpluginclassmedia.cpp file | annotate | diff | revisions
indra/llplugin/llpluginclassmedia.h file | annotate | diff | revisions
indra/llplugin/llplugincookiestore.cpp file | annotate | diff | revisions
indra/llplugin/llplugincookiestore.h file | annotate | diff | revisions
indra/llplugin/tests/llplugincookiestore_test.cpp file | annotate | diff | revisions
indra/media_plugins/cef/media_plugin_cef.cpp file | annotate | diff | revisions
indra/newview/app_settings/settings.xml file | annotate | diff | revisions
indra/newview/llappviewer.cpp file | annotate | diff | revisions
indra/newview/llfloaterfacebook.cpp file | annotate | diff | revisions
indra/newview/llfloaterflickr.cpp file | annotate | diff | revisions
indra/newview/llfloatertwitter.cpp file | annotate | diff | revisions
indra/newview/llmediactrl.cpp file | annotate | diff | revisions
indra/newview/llstartup.cpp file | annotate | diff | revisions
indra/newview/llviewermedia.cpp file | annotate | diff | revisions
indra/newview/llviewermedia.h file | annotate | diff | revisions
indra/newview/llwebprofile.cpp file | annotate | diff | revisions
indra/newview/skins/default/xui/en/floater_about.xml file | annotate | diff | revisions
indra/newview/skins/default/xui/en/floater_web_content.xml file | annotate | diff | revisions
indra/newview/skins/default/xui/en/panel_preferences_privacy.xml file | annotate | diff | revisions
indra/newview/skins/default/xui/en/panel_preferences_setup.xml file | annotate | diff | revisions
     1.1 --- a/autobuild.xml	Wed Feb 14 11:37:07 2018 +0200
     1.2 +++ b/autobuild.xml	Wed Feb 14 21:56:53 2018 +0100
     1.3 @@ -756,9 +756,9 @@
     1.4              <key>archive</key>
     1.5              <map>
     1.6                <key>hash</key>
     1.7 -              <string>bbdea742f2a89bcd6360e61e01d6be93</string>
     1.8 -              <key>url</key>
     1.9 -              <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>
    1.10 +              <string>35b3fca493235ff590c5bb58b28f56bd</string>
    1.11 +              <key>url</key>
    1.12 +              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/13031/79689/dullahan-1.1.1040_3.3239.1723.g071d1c1-darwin64-512263.tar.bz2</string>
    1.13              </map>
    1.14              <key>name</key>
    1.15              <string>darwin64</string>
    1.16 @@ -792,9 +792,9 @@
    1.17              <key>archive</key>
    1.18              <map>
    1.19                <key>hash</key>
    1.20 -              <string>31e11a74e0d3f1e5e4036cb5fea8d944</string>
    1.21 -              <key>url</key>
    1.22 -              <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>
    1.23 +              <string>dc8a50e9afc7ff974faec8301e8eb6a3</string>
    1.24 +              <key>url</key>
    1.25 +              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/13032/79696/dullahan-1.1.1040_3.3239.1723.g071d1c1-windows-512263.tar.bz2</string>
    1.26              </map>
    1.27              <key>name</key>
    1.28              <string>windows</string>
    1.29 @@ -804,16 +804,16 @@
    1.30              <key>archive</key>
    1.31              <map>
    1.32                <key>hash</key>
    1.33 -              <string>f965d244e7921c06ee79b68a4abcea3b</string>
    1.34 -              <key>url</key>
    1.35 -              <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>
    1.36 +              <string>fd45e9c73d334e0093a67b7b94abb994</string>
    1.37 +              <key>url</key>
    1.38 +              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/13033/79701/dullahan-1.1.1040_3.3239.1723.g071d1c1-windows64-512263.tar.bz2</string>
    1.39              </map>
    1.40              <key>name</key>
    1.41              <string>windows64</string>
    1.42            </map>
    1.43          </map>
    1.44          <key>version</key>
    1.45 -        <string>1.1.820_3.3071.1634.g9cc59c8</string>
    1.46 +        <string>1.1.1040_3.3239.1723.g071d1c1</string>
    1.47        </map>
    1.48        <key>elfio</key>
    1.49        <map>
    1.50 @@ -3604,9 +3604,9 @@
    1.51              <key>archive</key>
    1.52              <map>
    1.53                <key>hash</key>
    1.54 -              <string>c5e6d9440e3a4a12102dd2bbb703963e</string>
    1.55 -              <key>url</key>
    1.56 -              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/2225/4736/vlc_bin-2.2.4.502214-darwin64-502214.tar.bz2</string>
    1.57 +              <string>e5635e173c75dc0675b48ab5f5e4868b</string>
    1.58 +              <key>url</key>
    1.59 +              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/12143/71451/vlc_bin-2.2.8.511703-darwin64-511703.tar.bz2</string>
    1.60              </map>
    1.61              <key>name</key>
    1.62              <string>darwin64</string>
    1.63 @@ -3640,9 +3640,9 @@
    1.64              <key>archive</key>
    1.65              <map>
    1.66                <key>hash</key>
    1.67 -              <string>dc37f7cc77a62891bb9ae46c9e19f95e</string>
    1.68 -              <key>url</key>
    1.69 -              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1219/2834/vlc_bin-2.2.4.501207-windows-501207.tar.bz2</string>
    1.70 +              <string>add560654a53cb1c554044a4fac3c718</string>
    1.71 +              <key>url</key>
    1.72 +              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/12144/71458/vlc_bin-2.2.8.511703-windows-511703.tar.bz2</string>
    1.73              </map>
    1.74              <key>name</key>
    1.75              <string>windows</string>
    1.76 @@ -3652,16 +3652,16 @@
    1.77              <key>archive</key>
    1.78              <map>
    1.79                <key>hash</key>
    1.80 -              <string>148ee599afeba9794de14ca433389504</string>
    1.81 -              <key>url</key>
    1.82 -              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1218/2829/vlc_bin-2.2.4.501207-windows64-501207.tar.bz2</string>
    1.83 +              <string>94bf04b49acc1e1bf2c06e2232f8a083</string>
    1.84 +              <key>url</key>
    1.85 +              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/12145/71463/vlc_bin-2.2.8.511703-windows64-511703.tar.bz2</string>
    1.86              </map>
    1.87              <key>name</key>
    1.88              <string>windows64</string>
    1.89            </map>
    1.90          </map>
    1.91          <key>version</key>
    1.92 -        <string>2.2.4.502214</string>
    1.93 +        <string>2.2.8.511703</string>
    1.94        </map>
    1.95        <key>xmlrpc-epi</key>
    1.96        <map>
     2.1 --- a/indra/llplugin/CMakeLists.txt	Wed Feb 14 11:37:07 2018 +0200
     2.2 +++ b/indra/llplugin/CMakeLists.txt	Wed Feb 14 21:56:53 2018 +0100
     2.3 @@ -29,7 +29,6 @@
     2.4  
     2.5  set(llplugin_SOURCE_FILES
     2.6      llpluginclassmedia.cpp
     2.7 -    llplugincookiestore.cpp
     2.8      llplugininstance.cpp
     2.9      llpluginmessage.cpp
    2.10      llpluginmessagepipe.cpp
    2.11 @@ -43,7 +42,6 @@
    2.12  
    2.13      llpluginclassmedia.h
    2.14      llpluginclassmediaowner.h
    2.15 -    llplugincookiestore.h
    2.16      llplugininstance.h
    2.17      llpluginmessage.h
    2.18      llpluginmessageclasses.h
    2.19 @@ -70,20 +68,3 @@
    2.20  
    2.21  add_subdirectory(slplugin)
    2.22  
    2.23 -# Add tests
    2.24 -if (LL_TESTS)
    2.25 -    include(LLAddBuildTest)
    2.26 -    # UNIT TESTS
    2.27 -    SET(llplugin_TEST_SOURCE_FILES
    2.28 -      llplugincookiestore.cpp
    2.29 -      )
    2.30 -
    2.31 -    # llplugincookiestore has a dependency on curl, so we need to link the curl library into the test.
    2.32 -    set_source_files_properties(
    2.33 -      llplugincookiestore.cpp
    2.34 -      PROPERTIES
    2.35 -        LL_TEST_ADDITIONAL_LIBRARIES "${CURL_LIBRARIES};${NGHTTP2_LIBRARIES}"
    2.36 -      )
    2.37 -
    2.38 -    LL_ADD_PROJECT_UNIT_TESTS(llplugin "${llplugin_TEST_SOURCE_FILES}")
    2.39 -endif (LL_TESTS)
     3.1 --- a/indra/llplugin/llpluginclassmedia.cpp	Wed Feb 14 11:37:07 2018 +0200
     3.2 +++ b/indra/llplugin/llpluginclassmedia.cpp	Wed Feb 14 21:56:53 2018 +0100
     3.3 @@ -31,6 +31,9 @@
     3.4  
     3.5  #include "llpluginclassmedia.h"
     3.6  #include "llpluginmessageclasses.h"
     3.7 +#include "llcontrol.h"
     3.8 +
     3.9 +extern LLControlGroup gSavedSettings;    
    3.10  
    3.11  static int LOW_PRIORITY_TEXTURE_SIZE_DEFAULT = 256;
    3.12  
    3.13 @@ -794,15 +797,22 @@
    3.14  	return result;
    3.15  }
    3.16  
    3.17 -void LLPluginClassMedia::sendPickFileResponse(const std::string &file)
    3.18 +void LLPluginClassMedia::sendPickFileResponse(const std::vector<std::string> files)
    3.19  {
    3.20  	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file_response");
    3.21 -	message.setValue("file", file);
    3.22  	if(mPlugin && mPlugin->isBlocked())
    3.23  	{
    3.24  		// If the plugin sent a blocking pick-file request, the response should unblock it.
    3.25  		message.setValueBoolean("blocking_response", true);
    3.26  	}
    3.27 +
    3.28 +	LLSD file_list = LLSD::emptyArray();
    3.29 +	for (std::vector<std::string>::const_iterator in_iter = files.begin(); in_iter != files.end(); ++in_iter)
    3.30 +	{
    3.31 +		file_list.append(LLSD::String(*in_iter));
    3.32 +	}
    3.33 +	message.setValueLLSD("file_list", file_list);
    3.34 +
    3.35  	sendMessage(message);
    3.36  }
    3.37  
    3.38 @@ -838,11 +848,17 @@
    3.39  	sendMessage(message);
    3.40  }
    3.41  
    3.42 -void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path_cache, const std::string &user_data_path_cookies)
    3.43 +void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path_cache,
    3.44 +										 const std::string &user_data_path_cookies,
    3.45 +										 const std::string &user_data_path_cef_log)
    3.46  {
    3.47  	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "set_user_data_path");
    3.48  	message.setValue("cache_path", user_data_path_cache);
    3.49  	message.setValue("cookies_path", user_data_path_cookies);
    3.50 +	message.setValue("cef_log_file", user_data_path_cef_log);
    3.51 +
    3.52 +	bool cef_verbose_log = gSavedSettings.getBOOL("CefVerboseLog");
    3.53 +	message.setValueBoolean("cef_verbose_log", cef_verbose_log);
    3.54  	sendMessage(message);
    3.55  }
    3.56  
    3.57 @@ -1100,6 +1116,7 @@
    3.58  		}
    3.59  		else if(message_name == "pick_file")
    3.60  		{
    3.61 +			mIsMultipleFilePick = message.getValueBoolean("multiple_files");
    3.62  			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PICK_FILE_REQUEST);
    3.63  		}
    3.64  		else if(message_name == "auth_request")
    3.65 @@ -1161,7 +1178,12 @@
    3.66  		{
    3.67  			mClickURL = message.getValue("uri");
    3.68  			mClickTarget = message.getValue("target");
    3.69 -			//mClickUUID = message.getValue("uuid");
    3.70 +
    3.71 +			// need a link to have a UUID that identifies it to a system further
    3.72 +			// upstream - plugin could make it but we have access to LLUUID here
    3.73 +			// so why don't we use it
    3.74 +			mClickUUID = LLUUID::generateNewID().asString();
    3.75 +
    3.76  			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_HREF);
    3.77  		}
    3.78  		else if(message_name == "click_nofollow")
    3.79 @@ -1176,13 +1198,6 @@
    3.80  			mStatusCode = message.getValueS32("status_code");
    3.81  			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAVIGATE_ERROR_PAGE);
    3.82  		}
    3.83 -		else if(message_name == "cookie_set")
    3.84 -		{
    3.85 -			if(mOwner)
    3.86 -			{
    3.87 -				mOwner->handleCookieSet(this, message.getValue("cookie"));
    3.88 -			}
    3.89 -		}
    3.90  		else if(message_name == "close_request")
    3.91  		{
    3.92  			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLOSE_REQUEST);
    3.93 @@ -1297,14 +1312,7 @@
    3.94  	sendMessage(message);
    3.95  }
    3.96  
    3.97 -void LLPluginClassMedia::set_cookies(const std::string &cookies)
    3.98 -{
    3.99 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_cookies");
   3.100 -	message.setValue("cookies", cookies);
   3.101 -	sendMessage(message);
   3.102 -}
   3.103 -
   3.104 -void LLPluginClassMedia::enable_cookies(bool enable)
   3.105 +void LLPluginClassMedia::cookies_enabled(bool enable)
   3.106  {
   3.107  	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "cookies_enabled");
   3.108  	message.setValueBoolean("enable", enable);
     4.1 --- a/indra/llplugin/llpluginclassmedia.h	Wed Feb 14 11:37:07 2018 +0200
     4.2 +++ b/indra/llplugin/llpluginclassmedia.h	Wed Feb 14 21:56:53 2018 +0100
     4.3 @@ -176,7 +176,7 @@
     4.4  	
     4.5  	F64 getCPUUsage();
     4.6  	
     4.7 -	void sendPickFileResponse(const std::string &file);
     4.8 +	void sendPickFileResponse(const std::vector<std::string> files);
     4.9  
    4.10  	void sendAuthResponse(bool ok, const std::string &username, const std::string &password);
    4.11  
    4.12 @@ -195,7 +195,7 @@
    4.13  	bool	canPaste() const { return mCanPaste; };
    4.14  	
    4.15  	// These can be called before init(), and they will be queued and sent before the media init message.
    4.16 -	void	setUserDataPath(const std::string &user_data_path_cache, const std::string &user_data_path_cookies);
    4.17 +	void	setUserDataPath(const std::string &user_data_path_cache, const std::string &user_data_path_cookies, const std::string &user_data_path_cef_log);
    4.18  	void	setLanguageCode(const std::string &language_code);
    4.19  	void	setPluginsEnabled(const bool enabled);
    4.20  	void	setJavascriptEnabled(const bool enabled);
    4.21 @@ -210,7 +210,7 @@
    4.22  	void clear_cache();
    4.23  	void clear_cookies();
    4.24  	void set_cookies(const std::string &cookies);
    4.25 -	void enable_cookies(bool enable);
    4.26 +	void cookies_enabled(bool enable);
    4.27  	void proxy_setup(bool enable, const std::string &host = LLStringUtil::null, int port = 0);
    4.28  	void browse_stop();
    4.29  	void browse_reload(bool ignore_cache = false);
    4.30 @@ -277,6 +277,9 @@
    4.31  	std::string	getAuthURL() const { return mAuthURL; };
    4.32  	std::string	getAuthRealm() const { return mAuthRealm; };
    4.33  
    4.34 +	// These are valid during MEDIA_EVENT_PICK_FILE_REQUEST
    4.35 +	bool getIsMultipleFilePick() const { return mIsMultipleFilePick; }
    4.36 +
    4.37  	// These are valid during MEDIA_EVENT_LINK_HOVERED
    4.38  	std::string	getHoverText() const { return mHoverText; };
    4.39  	std::string	getHoverLink() const { return mHoverLink; };
    4.40 @@ -435,6 +438,7 @@
    4.41  	std::string		mHoverText;
    4.42  	std::string		mHoverLink;
    4.43  	std::string     mFileDownloadFilename;
    4.44 +	bool			mIsMultipleFilePick;
    4.45  	
    4.46  	/////////////////////////////////////////
    4.47  	// media_time class
     5.1 --- a/indra/llplugin/llpluginclassmediaowner.h	Wed Feb 14 11:37:07 2018 +0200
     5.2 +++ b/indra/llplugin/llpluginclassmediaowner.h	Wed Feb 14 21:56:53 2018 +0100
     5.3 @@ -1,4 +1,4 @@
     5.4 -/** 
     5.5 +/**
     5.6   * @file llpluginclassmediaowner.h
     5.7   * @brief LLPluginClassMedia handles interaction with a plugin which knows about the "media" message class.
     5.8   *
     5.9 @@ -6,21 +6,21 @@
    5.10   * $LicenseInfo:firstyear=2008&license=viewerlgpl$
    5.11   * Second Life Viewer Source Code
    5.12   * Copyright (C) 2010, Linden Research, Inc.
    5.13 - * 
    5.14 + *
    5.15   * This library is free software; you can redistribute it and/or
    5.16   * modify it under the terms of the GNU Lesser General Public
    5.17   * License as published by the Free Software Foundation;
    5.18   * version 2.1 of the License only.
    5.19 - * 
    5.20 + *
    5.21   * This library is distributed in the hope that it will be useful,
    5.22   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.23   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    5.24   * Lesser General Public License for more details.
    5.25 - * 
    5.26 + *
    5.27   * You should have received a copy of the GNU Lesser General Public
    5.28   * License along with this library; if not, write to the Free Software
    5.29   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
    5.30 - * 
    5.31 + *
    5.32   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
    5.33   * $/LicenseInfo$
    5.34   * @endcond
    5.35 @@ -34,18 +34,17 @@
    5.36  #include <queue>
    5.37  
    5.38  class LLPluginClassMedia;
    5.39 -class LLPluginCookieStore;
    5.40  
    5.41  class LLPluginClassMediaOwner
    5.42  {
    5.43  public:
    5.44  	typedef enum
    5.45  	{
    5.46 -		MEDIA_EVENT_CONTENT_UPDATED,		// contents/dirty rect have updated 
    5.47 +		MEDIA_EVENT_CONTENT_UPDATED,		// contents/dirty rect have updated
    5.48  		MEDIA_EVENT_TIME_DURATION_UPDATED,	// current time and/or duration have updated
    5.49  		MEDIA_EVENT_SIZE_CHANGED,			// media size has changed
    5.50  		MEDIA_EVENT_CURSOR_CHANGED,			// plugin has requested a cursor change
    5.51 -		
    5.52 +
    5.53  		MEDIA_EVENT_NAVIGATE_BEGIN,			// browser has begun navigation
    5.54  		MEDIA_EVENT_NAVIGATE_COMPLETE,		// browser has finished navigation
    5.55  		MEDIA_EVENT_PROGRESS_UPDATED,		// browser has updated loading progress
    5.56 @@ -58,8 +57,8 @@
    5.57  		MEDIA_EVENT_CLOSE_REQUEST,			// The plugin requested its window be closed (currently hooked up to javascript window.close in webkit)
    5.58  		MEDIA_EVENT_PICK_FILE_REQUEST,		// The plugin wants the user to pick a file
    5.59  		MEDIA_EVENT_GEOMETRY_CHANGE,		// The plugin requested its window geometry be changed (per the javascript window interface)
    5.60 -	
    5.61 -		MEDIA_EVENT_PLUGIN_FAILED_LAUNCH,	// The plugin failed to launch 
    5.62 +
    5.63 +		MEDIA_EVENT_PLUGIN_FAILED_LAUNCH,	// The plugin failed to launch
    5.64  		MEDIA_EVENT_PLUGIN_FAILED,			// The plugin died unexpectedly
    5.65  
    5.66  		MEDIA_EVENT_AUTH_REQUEST,			// The plugin wants to display an auth dialog
    5.67 @@ -69,9 +68,9 @@
    5.68  		MEDIA_EVENT_DEBUG_MESSAGE,			// plugin sending back debug information for host to process
    5.69  
    5.70  		MEDIA_EVENT_LINK_HOVERED			// Got a "link hovered" event from the plugin
    5.71 -		
    5.72 +
    5.73  	} EMediaEvent;
    5.74 -	
    5.75 +
    5.76  	typedef enum
    5.77  	{
    5.78  		MEDIA_NONE,			// Uninitialized -- no useful state
    5.79 @@ -81,12 +80,11 @@
    5.80  		MEDIA_PLAYING,		// playing (only for time-based media)
    5.81  		MEDIA_PAUSED,		// paused (only for time-based media)
    5.82  		MEDIA_DONE			// finished playing (only for time-based media)
    5.83 -	
    5.84 +
    5.85  	} EMediaStatus;
    5.86 -	
    5.87 +
    5.88  	virtual ~LLPluginClassMediaOwner() {};
    5.89  	virtual void handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent /*event*/) {};
    5.90 -	virtual void handleCookieSet(LLPluginClassMedia* /*self*/, const std::string &/*cookie*/) {};
    5.91  };
    5.92  
    5.93  #endif // LL_LLPLUGINCLASSMEDIAOWNER_H
     6.1 --- a/indra/llplugin/llplugincookiestore.cpp	Wed Feb 14 11:37:07 2018 +0200
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,689 +0,0 @@
     6.4 -/** 
     6.5 - * @file llplugincookiestore.cpp
     6.6 - * @brief LLPluginCookieStore provides central storage for http cookies used by plugins
     6.7 - *
     6.8 - * @cond
     6.9 - * $LicenseInfo:firstyear=2010&license=viewerlgpl$
    6.10 - * Second Life Viewer Source Code
    6.11 - * Copyright (C) 2010, Linden Research, Inc.
    6.12 - * 
    6.13 - * This library is free software; you can redistribute it and/or
    6.14 - * modify it under the terms of the GNU Lesser General Public
    6.15 - * License as published by the Free Software Foundation;
    6.16 - * version 2.1 of the License only.
    6.17 - * 
    6.18 - * This library is distributed in the hope that it will be useful,
    6.19 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.20 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    6.21 - * Lesser General Public License for more details.
    6.22 - * 
    6.23 - * You should have received a copy of the GNU Lesser General Public
    6.24 - * License along with this library; if not, write to the Free Software
    6.25 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
    6.26 - * 
    6.27 - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
    6.28 - * $/LicenseInfo$
    6.29 - * @endcond
    6.30 - */
    6.31 -
    6.32 -#include "linden_common.h"
    6.33 -#include "llstl.h"
    6.34 -#include "indra_constants.h"
    6.35 -
    6.36 -#include "llplugincookiestore.h"
    6.37 -#include <iostream>
    6.38 -
    6.39 -// for curl_getdate() (apparently parsing RFC 1123 dates is hard)
    6.40 -#include <curl/curl.h>
    6.41 -
    6.42 -LLPluginCookieStore::LLPluginCookieStore():
    6.43 -	mHasChangedCookies(false)
    6.44 -{
    6.45 -}
    6.46 -
    6.47 -
    6.48 -LLPluginCookieStore::~LLPluginCookieStore()
    6.49 -{
    6.50 -	clearCookies();
    6.51 -}
    6.52 -
    6.53 -
    6.54 -LLPluginCookieStore::Cookie::Cookie(const std::string &s, std::string::size_type cookie_start, std::string::size_type cookie_end):
    6.55 -	mCookie(s, cookie_start, cookie_end - cookie_start),
    6.56 -	mNameStart(0), mNameEnd(0),
    6.57 -	mValueStart(0), mValueEnd(0),
    6.58 -	mDomainStart(0), mDomainEnd(0),
    6.59 -	mPathStart(0), mPathEnd(0),
    6.60 -	mDead(false), mChanged(true)
    6.61 -{
    6.62 -}
    6.63 -
    6.64 -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)
    6.65 -{
    6.66 -	Cookie *result = new Cookie(s, cookie_start, cookie_end);
    6.67 -
    6.68 -	if(!result->parse(host))
    6.69 -	{
    6.70 -		delete result;
    6.71 -		result = NULL;
    6.72 -	}
    6.73 -	
    6.74 -	return result;
    6.75 -}
    6.76 -
    6.77 -std::string LLPluginCookieStore::Cookie::getKey() const
    6.78 -{
    6.79 -	std::string result;
    6.80 -	if(mDomainEnd > mDomainStart)
    6.81 -	{
    6.82 -		result += mCookie.substr(mDomainStart, mDomainEnd - mDomainStart);
    6.83 -	}
    6.84 -	result += ';';
    6.85 -	if(mPathEnd > mPathStart)
    6.86 -	{
    6.87 -		result += mCookie.substr(mPathStart, mPathEnd - mPathStart);
    6.88 -	}
    6.89 -	result += ';';
    6.90 -	result += mCookie.substr(mNameStart, mNameEnd - mNameStart);
    6.91 -	return result;
    6.92 -}
    6.93 -
    6.94 -std::string LLPluginCookieStore::Cookie::getDomain() const
    6.95 -{
    6.96 -	std::string result;
    6.97 -	if(mDomainEnd > mDomainStart)
    6.98 -	{
    6.99 -		result += mCookie.substr(mDomainStart, mDomainEnd - mDomainStart);
   6.100 -	}
   6.101 -	return result;
   6.102 -}
   6.103 -
   6.104 -bool LLPluginCookieStore::Cookie::parse(const std::string &host)
   6.105 -{
   6.106 -	bool first_field = true;
   6.107 -
   6.108 -	std::string::size_type cookie_end = mCookie.size();
   6.109 -	std::string::size_type field_start = 0;
   6.110 -
   6.111 -	LL_DEBUGS("CookieStoreParse") << "parsing cookie: " << mCookie << LL_ENDL;
   6.112 -	while(field_start < cookie_end)
   6.113 -	{
   6.114 -		// Finding the start of the next field requires honoring special quoting rules
   6.115 -		// see the definition of 'quoted-string' in rfc2616 for details
   6.116 -		std::string::size_type next_field_start = findFieldEnd(field_start);
   6.117 -
   6.118 -		// The end of this field should not include the terminating ';' or any trailing whitespace
   6.119 -		std::string::size_type field_end = mCookie.find_last_not_of("; ", next_field_start);
   6.120 -		if(field_end == std::string::npos || field_end < field_start)
   6.121 -		{
   6.122 -			// This field was empty or all whitespace.  Set end = start so it shows as empty.
   6.123 -			field_end = field_start;
   6.124 -		}
   6.125 -		else if (field_end < next_field_start)
   6.126 -		{
   6.127 -			// we actually want the index of the char _after_ what 'last not of' found
   6.128 -			++field_end;
   6.129 -		}
   6.130 -		
   6.131 -		// find the start of the actual name (skip separator and possible whitespace)
   6.132 -		std::string::size_type name_start = mCookie.find_first_not_of("; ", field_start);
   6.133 -		if(name_start == std::string::npos || name_start > next_field_start)
   6.134 -		{
   6.135 -			// Again, nothing but whitespace.
   6.136 -			name_start = field_start;
   6.137 -		}
   6.138 -		
   6.139 -		// the name and value are separated by the first equals sign
   6.140 -		std::string::size_type name_value_sep = mCookie.find_first_of("=", name_start);
   6.141 -		if(name_value_sep == std::string::npos || name_value_sep > field_end)
   6.142 -		{
   6.143 -			// No separator found, so this is a field without an = 
   6.144 -			name_value_sep = field_end;
   6.145 -		}
   6.146 -		
   6.147 -		// the name end is before the name-value separator
   6.148 -		std::string::size_type name_end = mCookie.find_last_not_of("= ", name_value_sep);
   6.149 -		if(name_end == std::string::npos || name_end < name_start)
   6.150 -		{
   6.151 -			// I'm not sure how we'd hit this case... it seems like it would have to be an empty name.
   6.152 -			name_end = name_start;
   6.153 -		}
   6.154 -		else if (name_end < name_value_sep)
   6.155 -		{
   6.156 -			// we actually want the index of the char _after_ what 'last not of' found
   6.157 -			++name_end;
   6.158 -		}
   6.159 -		
   6.160 -		// Value is between the name-value sep and the end of the field.
   6.161 -		std::string::size_type value_start = mCookie.find_first_not_of("= ", name_value_sep);
   6.162 -		if(value_start == std::string::npos || value_start > field_end)
   6.163 -		{
   6.164 -			// All whitespace or empty value
   6.165 -			value_start = field_end;
   6.166 -		}
   6.167 -		std::string::size_type value_end = mCookie.find_last_not_of("; ", field_end);
   6.168 -		if(value_end == std::string::npos || value_end < value_start)
   6.169 -		{
   6.170 -			// All whitespace or empty value
   6.171 -			value_end = value_start;
   6.172 -		}
   6.173 -		else if (value_end < field_end)
   6.174 -		{
   6.175 -			// we actually want the index of the char _after_ what 'last not of' found
   6.176 -			++value_end;
   6.177 -		}
   6.178 -
   6.179 -		LL_DEBUGS("CookieStoreParse") 
   6.180 -			<< "    field name: \"" << mCookie.substr(name_start, name_end - name_start) 
   6.181 -			<< "\", value: \"" << mCookie.substr(value_start, value_end - value_start) << "\""
   6.182 -			<< LL_ENDL;
   6.183 -				
   6.184 -		// See whether this field is one we know
   6.185 -		if(first_field)
   6.186 -		{
   6.187 -			// The first field is the name=value pair
   6.188 -			mNameStart = name_start;
   6.189 -			mNameEnd = name_end;
   6.190 -			mValueStart = value_start;
   6.191 -			mValueEnd = value_end;
   6.192 -			first_field = false;
   6.193 -		}
   6.194 -		else
   6.195 -		{
   6.196 -			// Subsequent fields must come from the set in rfc2109
   6.197 -			if(matchName(name_start, name_end, "expires"))
   6.198 -			{
   6.199 -				std::string date_string(mCookie, value_start, value_end - value_start); 
   6.200 -				// If the cookie contains an "expires" field, it MUST contain a parsable date.
   6.201 -				
   6.202 -				// HACK: LLDate apparently can't PARSE an rfc1123-format date, even though it can GENERATE one.
   6.203 -				//  The curl function curl_getdate can do this, but I'm hesitant to unilaterally introduce a curl dependency in LLDate.
   6.204 -#if 1
   6.205 -				time_t date = curl_getdate(date_string.c_str(), NULL );
   6.206 -				mDate.secondsSinceEpoch((F64)date);
   6.207 -				LL_DEBUGS("CookieStoreParse") << "        expire date parsed to: " << mDate.asRFC1123() << LL_ENDL;
   6.208 -#else
   6.209 -				// This doesn't work (rfc1123-format dates cause it to fail)
   6.210 -				if(!mDate.fromString(date_string))
   6.211 -				{
   6.212 -					// Date failed to parse.
   6.213 -					LL_WARNS("CookieStoreParse") << "failed to parse cookie's expire date: " << date << LL_ENDL;
   6.214 -					return false;
   6.215 -				}
   6.216 -#endif
   6.217 -			}
   6.218 -			else if(matchName(name_start, name_end, "domain"))
   6.219 -			{
   6.220 -				mDomainStart = value_start;
   6.221 -				mDomainEnd = value_end;
   6.222 -			}
   6.223 -			else if(matchName(name_start, name_end, "path"))
   6.224 -			{
   6.225 -				mPathStart = value_start;
   6.226 -				mPathEnd = value_end;
   6.227 -			}
   6.228 -			else if(matchName(name_start, name_end, "max-age"))
   6.229 -			{
   6.230 -				// TODO: how should we handle this?
   6.231 -			}
   6.232 -			else if(matchName(name_start, name_end, "secure"))
   6.233 -			{
   6.234 -				// We don't care about the value of this field (yet)
   6.235 -			}
   6.236 -			else if(matchName(name_start, name_end, "version"))
   6.237 -			{
   6.238 -				// We don't care about the value of this field (yet)
   6.239 -			}
   6.240 -			else if(matchName(name_start, name_end, "comment"))
   6.241 -			{
   6.242 -				// We don't care about the value of this field (yet)
   6.243 -			}
   6.244 -			else if(matchName(name_start, name_end, "httponly"))
   6.245 -			{
   6.246 -				// We don't care about the value of this field (yet)
   6.247 -			}
   6.248 -			else
   6.249 -			{
   6.250 -				// An unknown field is a parse failure
   6.251 -				LL_WARNS("CookieStoreParse") << "unexpected field name: " << mCookie.substr(name_start, name_end - name_start) << LL_ENDL;
   6.252 -				return false;
   6.253 -			}
   6.254 -			
   6.255 -		}
   6.256 -
   6.257 -		
   6.258 -		// move on to the next field, skipping this field's separator and any leading whitespace
   6.259 -		field_start = mCookie.find_first_not_of("; ", next_field_start);
   6.260 -	}
   6.261 -		
   6.262 -	// The cookie MUST have a name
   6.263 -	if(mNameEnd <= mNameStart)
   6.264 -		return false;
   6.265 -	
   6.266 -	// If the cookie doesn't have a domain, add the current host as the domain.
   6.267 -	if(mDomainEnd <= mDomainStart)
   6.268 -	{
   6.269 -		if(host.empty())
   6.270 -		{
   6.271 -			// no domain and no current host -- this is a parse failure.
   6.272 -			return false;
   6.273 -		}
   6.274 -		
   6.275 -		// Figure out whether this cookie ended with a ";" or not...
   6.276 -		std::string::size_type last_char = mCookie.find_last_not_of(" ");
   6.277 -		if((last_char != std::string::npos) && (mCookie[last_char] != ';'))
   6.278 -		{
   6.279 -			mCookie += ";";
   6.280 -		}
   6.281 -		
   6.282 -		mCookie += " domain=";
   6.283 -		mDomainStart = mCookie.size();
   6.284 -		mCookie += host;
   6.285 -		mDomainEnd = mCookie.size();
   6.286 -		
   6.287 -		LL_DEBUGS("CookieStoreParse") << "added domain (" << mDomainStart << " to " << mDomainEnd << "), new cookie is: " << mCookie << LL_ENDL;
   6.288 -	}
   6.289 -
   6.290 -	// If the cookie doesn't have a path, add "/".
   6.291 -	if(mPathEnd <= mPathStart)
   6.292 -	{
   6.293 -		// Figure out whether this cookie ended with a ";" or not...
   6.294 -		std::string::size_type last_char = mCookie.find_last_not_of(" ");
   6.295 -		if((last_char != std::string::npos) && (mCookie[last_char] != ';'))
   6.296 -		{
   6.297 -			mCookie += ";";
   6.298 -		}
   6.299 -		
   6.300 -		mCookie += " path=";
   6.301 -		mPathStart = mCookie.size();
   6.302 -		mCookie += "/";
   6.303 -		mPathEnd = mCookie.size();
   6.304 -		
   6.305 -		LL_DEBUGS("CookieStoreParse") << "added path (" << mPathStart << " to " << mPathEnd << "), new cookie is: " << mCookie << LL_ENDL;
   6.306 -	}
   6.307 -	
   6.308 -	
   6.309 -	return true;
   6.310 -}
   6.311 -
   6.312 -std::string::size_type LLPluginCookieStore::Cookie::findFieldEnd(std::string::size_type start, std::string::size_type end)
   6.313 -{
   6.314 -	std::string::size_type result = start;
   6.315 -	
   6.316 -	if(end == std::string::npos)
   6.317 -		end = mCookie.size();
   6.318 -	
   6.319 -	bool in_quotes = false;
   6.320 -	for(; (result < end); result++)
   6.321 -	{
   6.322 -		switch(mCookie[result])
   6.323 -		{
   6.324 -			case '\\':
   6.325 -				if(in_quotes)
   6.326 -					result++; // The next character is backslash-quoted.  Skip over it.
   6.327 -			break;
   6.328 -			case '"':
   6.329 -				in_quotes = !in_quotes;
   6.330 -			break;
   6.331 -			case ';':
   6.332 -				if(!in_quotes)
   6.333 -					return result;
   6.334 -			break;
   6.335 -		}		
   6.336 -	}
   6.337 -	
   6.338 -	// If we got here, no ';' was found.
   6.339 -	return end;
   6.340 -}
   6.341 -
   6.342 -bool LLPluginCookieStore::Cookie::matchName(std::string::size_type start, std::string::size_type end, const char *name)
   6.343 -{
   6.344 -	// NOTE: this assumes 'name' is already in lowercase.  The code which uses it should be able to arrange this...
   6.345 -	
   6.346 -	while((start < end) && (*name != '\0'))
   6.347 -	{
   6.348 -		if(tolower(mCookie[start]) != *name)
   6.349 -			return false;
   6.350 -			
   6.351 -		start++;
   6.352 -		name++;
   6.353 -	}
   6.354 -	
   6.355 -	// iff both strings hit the end at the same time, they're equal.
   6.356 -	return ((start == end) && (*name == '\0'));
   6.357 -}
   6.358 -
   6.359 -std::string LLPluginCookieStore::getAllCookies()
   6.360 -{
   6.361 -	std::stringstream result;
   6.362 -	writeAllCookies(result);
   6.363 -	return result.str();
   6.364 -}
   6.365 -
   6.366 -void LLPluginCookieStore::writeAllCookies(std::ostream& s)
   6.367 -{
   6.368 -	cookie_map_t::iterator iter;
   6.369 -	for(iter = mCookies.begin(); iter != mCookies.end(); iter++)
   6.370 -	{
   6.371 -		// Don't return expired cookies
   6.372 -		if(!iter->second->isDead())
   6.373 -		{
   6.374 -			s << (iter->second->getCookie()) << "\n";
   6.375 -		}
   6.376 -	}
   6.377 -
   6.378 -}
   6.379 -
   6.380 -std::string LLPluginCookieStore::getPersistentCookies()
   6.381 -{
   6.382 -	std::stringstream result;
   6.383 -	writePersistentCookies(result);
   6.384 -	return result.str();
   6.385 -}
   6.386 -
   6.387 -void LLPluginCookieStore::writePersistentCookies(std::ostream& s)
   6.388 -{
   6.389 -	cookie_map_t::iterator iter;
   6.390 -	for(iter = mCookies.begin(); iter != mCookies.end(); iter++)
   6.391 -	{
   6.392 -		// Don't return expired cookies or session cookies
   6.393 -		if(!iter->second->isDead() && !iter->second->isSessionCookie())
   6.394 -		{
   6.395 -			s << iter->second->getCookie() << "\n";
   6.396 -		}
   6.397 -	}
   6.398 -}
   6.399 -
   6.400 -std::string LLPluginCookieStore::getChangedCookies(bool clear_changed)
   6.401 -{
   6.402 -	std::stringstream result;
   6.403 -	writeChangedCookies(result, clear_changed);
   6.404 -	
   6.405 -	return result.str();
   6.406 -}
   6.407 -
   6.408 -void LLPluginCookieStore::writeChangedCookies(std::ostream& s, bool clear_changed)
   6.409 -{
   6.410 -	if(mHasChangedCookies)
   6.411 -	{
   6.412 -		LL_DEBUGS() << "returning changed cookies: " << LL_ENDL;
   6.413 -		cookie_map_t::iterator iter;
   6.414 -		for(iter = mCookies.begin(); iter != mCookies.end(); )
   6.415 -		{
   6.416 -			cookie_map_t::iterator next = iter;
   6.417 -			next++;
   6.418 -			
   6.419 -			// Only return cookies marked as "changed"
   6.420 -			if(iter->second->isChanged())
   6.421 -			{
   6.422 -				s << iter->second->getCookie() << "\n";
   6.423 -
   6.424 -				LL_DEBUGS() << "    " << iter->second->getCookie() << LL_ENDL;
   6.425 -
   6.426 -				// If requested, clear the changed mark
   6.427 -				if(clear_changed)
   6.428 -				{
   6.429 -					if(iter->second->isDead())
   6.430 -					{
   6.431 -						// If this cookie was previously marked dead, it needs to be removed entirely.	
   6.432 -						delete iter->second;
   6.433 -						mCookies.erase(iter);
   6.434 -					}
   6.435 -					else
   6.436 -					{
   6.437 -						// Not dead, just mark as not changed.
   6.438 -						iter->second->setChanged(false);
   6.439 -					}
   6.440 -				}
   6.441 -			}
   6.442 -			
   6.443 -			iter = next;
   6.444 -		}
   6.445 -	}
   6.446 -	
   6.447 -	if(clear_changed)
   6.448 -		mHasChangedCookies = false;
   6.449 -}
   6.450 -
   6.451 -void LLPluginCookieStore::setAllCookies(const std::string &cookies, bool mark_changed)
   6.452 -{
   6.453 -	clearCookies();
   6.454 -	setCookies(cookies, mark_changed);
   6.455 -}
   6.456 -
   6.457 -void LLPluginCookieStore::readAllCookies(std::istream& s, bool mark_changed)
   6.458 -{
   6.459 -	clearCookies();
   6.460 -	readCookies(s, mark_changed);
   6.461 -}
   6.462 -	
   6.463 -void LLPluginCookieStore::setCookies(const std::string &cookies, bool mark_changed)
   6.464 -{
   6.465 -	std::string::size_type start = 0;
   6.466 -
   6.467 -	while(start != std::string::npos)
   6.468 -	{
   6.469 -		std::string::size_type end = cookies.find_first_of("\r\n", start);
   6.470 -		if(end > start)
   6.471 -		{
   6.472 -			// The line is non-empty.  Try to create a cookie from it.
   6.473 -			setOneCookie(cookies, start, end, mark_changed);
   6.474 -		}
   6.475 -		start = cookies.find_first_not_of("\r\n ", end);
   6.476 -	}
   6.477 -}
   6.478 -
   6.479 -void LLPluginCookieStore::setCookiesFromHost(const std::string &cookies, const std::string &host, bool mark_changed)
   6.480 -{
   6.481 -	std::string::size_type start = 0;
   6.482 -
   6.483 -	while(start != std::string::npos)
   6.484 -	{
   6.485 -		std::string::size_type end = cookies.find_first_of("\r\n", start);
   6.486 -		if(end > start)
   6.487 -		{
   6.488 -			// The line is non-empty.  Try to create a cookie from it.
   6.489 -			setOneCookie(cookies, start, end, mark_changed, host);
   6.490 -		}
   6.491 -		start = cookies.find_first_not_of("\r\n ", end);
   6.492 -	}
   6.493 -}
   6.494 -			
   6.495 -void LLPluginCookieStore::readCookies(std::istream& s, bool mark_changed)
   6.496 -{
   6.497 -	std::string line;
   6.498 -	while(s.good() && !s.eof())
   6.499 -	{
   6.500 -		std::getline(s, line);
   6.501 -		if(!line.empty())
   6.502 -		{
   6.503 -			// Try to create a cookie from this line.
   6.504 -			setOneCookie(line, 0, std::string::npos, mark_changed);
   6.505 -		}
   6.506 -	}
   6.507 -}
   6.508 -
   6.509 -std::string LLPluginCookieStore::quoteString(const std::string &s)
   6.510 -{
   6.511 -	std::stringstream result;
   6.512 -	
   6.513 -	result << '"';
   6.514 -	
   6.515 -	for(std::string::size_type i = 0; i < s.size(); ++i)
   6.516 -	{
   6.517 -		char c = s[i];
   6.518 -		switch(c)
   6.519 -		{
   6.520 -			// All these separators need to be quoted in HTTP headers, according to section 2.2 of rfc 2616:
   6.521 -			case '(': case ')': case '<': case '>': case '@':
   6.522 -			case ',': case ';': case ':': case '\\': case '"':
   6.523 -			case '/': case '[': case ']': case '?': case '=':
   6.524 -			case '{': case '}':	case ' ': case '\t':
   6.525 -				result << '\\';
   6.526 -			break;
   6.527 -		}
   6.528 -		
   6.529 -		result << c;
   6.530 -	}
   6.531 -	
   6.532 -	result << '"';
   6.533 -	
   6.534 -	return result.str();
   6.535 -}
   6.536 -
   6.537 -std::string LLPluginCookieStore::unquoteString(const std::string &s)
   6.538 -{
   6.539 -	std::stringstream result;
   6.540 -	
   6.541 -	bool in_quotes = false;
   6.542 -	
   6.543 -	for(std::string::size_type i = 0; i < s.size(); ++i)
   6.544 -	{
   6.545 -		char c = s[i];
   6.546 -		switch(c)
   6.547 -		{
   6.548 -			case '\\':
   6.549 -				if(in_quotes)
   6.550 -				{
   6.551 -					// The next character is backslash-quoted.  Pass it through untouched.
   6.552 -					++i; 
   6.553 -					if(i < s.size())
   6.554 -					{
   6.555 -						result << s[i];
   6.556 -					}
   6.557 -					continue;
   6.558 -				}
   6.559 -			break;
   6.560 -			case '"':
   6.561 -				in_quotes = !in_quotes;
   6.562 -				continue;
   6.563 -			break;
   6.564 -		}
   6.565 -		
   6.566 -		result << c;
   6.567 -	}
   6.568 -	
   6.569 -	return result.str();
   6.570 -}
   6.571 -
   6.572 -// The flow for deleting a cookie is non-obvious enough that I should call it out here...
   6.573 -// Deleting a cookie is done by setting a cookie with the same name, path, and domain, but with an expire timestamp in the past.
   6.574 -// (This is exactly how a web server tells a browser to delete a cookie.)
   6.575 -// 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.
   6.576 -// 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
   6.577 -// delete operation (in the form of the expired cookie) is passed along.
   6.578 -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)
   6.579 -{
   6.580 -	Cookie *cookie = Cookie::createFromString(s, cookie_start, cookie_end, host);
   6.581 -	if(cookie)
   6.582 -	{
   6.583 -		LL_DEBUGS("CookieStoreUpdate") << "setting cookie: " << cookie->getCookie() << LL_ENDL;
   6.584 -		
   6.585 -		// Create a key for this cookie
   6.586 -		std::string key = cookie->getKey();
   6.587 -		
   6.588 -		// Check to see whether this cookie should have expired
   6.589 -		if(!cookie->isSessionCookie() && (cookie->getDate() < LLDate::now()))
   6.590 -		{
   6.591 -			// This cookie has expired.
   6.592 -			if(mark_changed)
   6.593 -			{
   6.594 -				// If we're marking cookies as changed, we should keep it anyway since we'll need to send it out with deltas.
   6.595 -				cookie->setDead(true);
   6.596 -				LL_DEBUGS("CookieStoreUpdate") << "    marking dead" << LL_ENDL;
   6.597 -			}
   6.598 -			else
   6.599 -			{
   6.600 -				// If we're not marking cookies as changed, we don't need to keep this cookie at all.
   6.601 -				// If the cookie was already in the list, delete it.
   6.602 -				removeCookie(key);
   6.603 -
   6.604 -				delete cookie;
   6.605 -				cookie = NULL;
   6.606 -
   6.607 -				LL_DEBUGS("CookieStoreUpdate") << "    removing" << LL_ENDL;
   6.608 -			}
   6.609 -		}
   6.610 -		
   6.611 -		if(cookie)
   6.612 -		{
   6.613 -			// If it already exists in the map, replace it.
   6.614 -			cookie_map_t::iterator iter = mCookies.find(key);
   6.615 -			if(iter != mCookies.end())
   6.616 -			{
   6.617 -				if(iter->second->getCookie() == cookie->getCookie())
   6.618 -				{
   6.619 -					// The new cookie is identical to the old -- don't mark as changed.
   6.620 -					// Just leave the old one in the map.
   6.621 -					delete cookie;
   6.622 -					cookie = NULL;
   6.623 -
   6.624 -					LL_DEBUGS("CookieStoreUpdate") << "    unchanged" << LL_ENDL;
   6.625 -				}
   6.626 -				else
   6.627 -				{
   6.628 -					// A matching cookie was already in the map.  Replace it.
   6.629 -					delete iter->second;
   6.630 -					iter->second = cookie;
   6.631 -					
   6.632 -					cookie->setChanged(mark_changed);
   6.633 -					if(mark_changed)
   6.634 -						mHasChangedCookies = true;
   6.635 -
   6.636 -					LL_DEBUGS("CookieStoreUpdate") << "    replacing" << LL_ENDL;
   6.637 -				}
   6.638 -			}
   6.639 -			else
   6.640 -			{
   6.641 -				// The cookie wasn't in the map.  Insert it.
   6.642 -				mCookies.insert(std::make_pair(key, cookie));
   6.643 -				
   6.644 -				cookie->setChanged(mark_changed);
   6.645 -				if(mark_changed)
   6.646 -					mHasChangedCookies = true;
   6.647 -
   6.648 -				LL_DEBUGS("CookieStoreUpdate") << "    adding" << LL_ENDL;
   6.649 -			}
   6.650 -		}
   6.651 -	}
   6.652 -	else
   6.653 -	{
   6.654 -		LL_WARNS("CookieStoreUpdate") << "failed to parse cookie: " << s.substr(cookie_start, cookie_end - cookie_start) << LL_ENDL;
   6.655 -	}
   6.656 -
   6.657 -}
   6.658 -
   6.659 -void LLPluginCookieStore::clearCookies()
   6.660 -{
   6.661 -	std::for_each(mCookies.begin(), mCookies.end(), DeletePairedPointer());
   6.662 -	mCookies.clear();
   6.663 -}
   6.664 -
   6.665 -void LLPluginCookieStore::removeCookie(const std::string &key)
   6.666 -{
   6.667 -	cookie_map_t::iterator iter = mCookies.find(key);
   6.668 -	if(iter != mCookies.end())
   6.669 -	{
   6.670 -		delete iter->second;
   6.671 -		mCookies.erase(iter);
   6.672 -	}
   6.673 -}
   6.674 -
   6.675 -void LLPluginCookieStore::removeCookiesByDomain(const std::string &domain)
   6.676 -{
   6.677 -	cookie_map_t::iterator iter = mCookies.begin();
   6.678 -	while(iter != mCookies.end())
   6.679 -	{ 
   6.680 -		if(iter->second->getDomain() == domain)
   6.681 -		{
   6.682 -            cookie_map_t::iterator doErase = iter;
   6.683 -            iter++;
   6.684 -			delete doErase->second;
   6.685 -			mCookies.erase(doErase);
   6.686 -		}
   6.687 -        else
   6.688 -        {
   6.689 -            iter++;
   6.690 -        }
   6.691 -	}
   6.692 -}
     7.1 --- a/indra/llplugin/llplugincookiestore.h	Wed Feb 14 11:37:07 2018 +0200
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,123 +0,0 @@
     7.4 -/** 
     7.5 - * @file llplugincookiestore.h
     7.6 - * @brief LLPluginCookieStore provides central storage for http cookies used by plugins
     7.7 - *
     7.8 - * @cond
     7.9 - * $LicenseInfo:firstyear=2010&license=viewerlgpl$
    7.10 - * Second Life Viewer Source Code
    7.11 - * Copyright (C) 2010, Linden Research, Inc.
    7.12 - * 
    7.13 - * This library is free software; you can redistribute it and/or
    7.14 - * modify it under the terms of the GNU Lesser General Public
    7.15 - * License as published by the Free Software Foundation;
    7.16 - * version 2.1 of the License only.
    7.17 - * 
    7.18 - * This library is distributed in the hope that it will be useful,
    7.19 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.20 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    7.21 - * Lesser General Public License for more details.
    7.22 - * 
    7.23 - * You should have received a copy of the GNU Lesser General Public
    7.24 - * License along with this library; if not, write to the Free Software
    7.25 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
    7.26 - * 
    7.27 - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
    7.28 - * $/LicenseInfo$
    7.29 - * @endcond
    7.30 - */
    7.31 -
    7.32 -#ifndef LL_LLPLUGINCOOKIESTORE_H
    7.33 -#define LL_LLPLUGINCOOKIESTORE_H
    7.34 -
    7.35 -#include "lldate.h"
    7.36 -#include <map>
    7.37 -#include <string>
    7.38 -#include <iostream>
    7.39 -
    7.40 -class LLPluginCookieStore
    7.41 -{
    7.42 -	LOG_CLASS(LLPluginCookieStore);
    7.43 -public:
    7.44 -	LLPluginCookieStore();
    7.45 -	~LLPluginCookieStore();
    7.46 -
    7.47 -	// gets all cookies currently in storage -- use when initializing a plugin
    7.48 -	std::string getAllCookies();
    7.49 -	void writeAllCookies(std::ostream& s);
    7.50 -	
    7.51 -	// gets only persistent cookies (i.e. not session cookies) -- use when writing cookies to a file
    7.52 -	std::string getPersistentCookies();
    7.53 -	void writePersistentCookies(std::ostream& s);
    7.54 -	
    7.55 -	// gets cookies which are marked as "changed" -- use when sending periodic updates to plugins
    7.56 -	std::string getChangedCookies(bool clear_changed = true);
    7.57 -	void writeChangedCookies(std::ostream& s, bool clear_changed = true);
    7.58 -	
    7.59 -	// (re)initializes internal data structures and bulk-sets cookies -- use when reading cookies from a file
    7.60 -	void setAllCookies(const std::string &cookies, bool mark_changed = false);
    7.61 -	void readAllCookies(std::istream& s, bool mark_changed = false);
    7.62 -	
    7.63 -	// sets one or more cookies (without reinitializing anything) -- use when receiving cookies from a plugin
    7.64 -	void setCookies(const std::string &cookies, bool mark_changed = true);
    7.65 -	void readCookies(std::istream& s, bool mark_changed = true);
    7.66 -
    7.67 -	// sets one or more cookies (without reinitializing anything), supplying a hostname the cookies came from -- use when setting a cookie manually
    7.68 -	void setCookiesFromHost(const std::string &cookies, const std::string &host, bool mark_changed = true);
    7.69 -
    7.70 -	// quote or unquote a string as per the definition of 'quoted-string' in rfc2616
    7.71 -	static std::string quoteString(const std::string &s);
    7.72 -	static std::string unquoteString(const std::string &s);
    7.73 -
    7.74 -	void removeCookiesByDomain(const std::string &domain);
    7.75 -	
    7.76 -private:
    7.77 -
    7.78 -	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);
    7.79 -
    7.80 -	class Cookie
    7.81 -	{
    7.82 -	public:
    7.83 -		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);
    7.84 -		
    7.85 -		// Construct a string from the cookie that uniquely represents it, to be used as a key in a std::map.
    7.86 -		std::string getKey() const;
    7.87 -		std::string getDomain() const;
    7.88 -		
    7.89 -		const std::string &getCookie() const { return mCookie; };
    7.90 -		bool isSessionCookie() const { return mDate.isNull(); };
    7.91 -
    7.92 -		bool isDead() const { return mDead; };
    7.93 -		void setDead(bool dead) { mDead = dead; };
    7.94 -		
    7.95 -		bool isChanged() const { return mChanged; };
    7.96 -		void setChanged(bool changed) { mChanged = changed; };
    7.97 -
    7.98 -		const LLDate &getDate() const { return mDate; };
    7.99 -		
   7.100 -	private:
   7.101 -		Cookie(const std::string &s, std::string::size_type cookie_start = 0, std::string::size_type cookie_end = std::string::npos);
   7.102 -		bool parse(const std::string &host);
   7.103 -		std::string::size_type findFieldEnd(std::string::size_type start = 0, std::string::size_type end = std::string::npos);
   7.104 -		bool matchName(std::string::size_type start, std::string::size_type end, const char *name);
   7.105 -		
   7.106 -		std::string mCookie;	// The full cookie, in RFC 2109 string format
   7.107 -		LLDate mDate;			// The expiration date of the cookie.  For session cookies, this will be a null date (mDate.isNull() is true).
   7.108 -		// Start/end indices of various parts of the cookie string.  Stored as indices into the string to save space and time.
   7.109 -		std::string::size_type mNameStart, mNameEnd;
   7.110 -		std::string::size_type mValueStart, mValueEnd;
   7.111 -		std::string::size_type mDomainStart, mDomainEnd;
   7.112 -		std::string::size_type mPathStart, mPathEnd;
   7.113 -		bool mDead;
   7.114 -		bool mChanged;
   7.115 -	};
   7.116 -	
   7.117 -	typedef std::map<std::string, Cookie*> cookie_map_t;
   7.118 -	
   7.119 -	cookie_map_t mCookies;
   7.120 -	bool mHasChangedCookies;
   7.121 -	
   7.122 -	void clearCookies();
   7.123 -	void removeCookie(const std::string &key);
   7.124 -};
   7.125 -
   7.126 -#endif // LL_LLPLUGINCOOKIESTORE_H
     8.1 --- a/indra/llplugin/tests/llplugincookiestore_test.cpp	Wed Feb 14 11:37:07 2018 +0200
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,207 +0,0 @@
     8.4 -/** 
     8.5 - * @file llplugincookiestore_test.cpp
     8.6 - * @brief Unit tests for LLPluginCookieStore.
     8.7 - *
     8.8 - * @cond
     8.9 - * $LicenseInfo:firstyear=2010&license=viewerlgpl$
    8.10 - * Second Life Viewer Source Code
    8.11 - * Copyright (C) 2010, Linden Research, Inc.
    8.12 - * 
    8.13 - * This library is free software; you can redistribute it and/or
    8.14 - * modify it under the terms of the GNU Lesser General Public
    8.15 - * License as published by the Free Software Foundation;
    8.16 - * version 2.1 of the License only.
    8.17 - * 
    8.18 - * This library is distributed in the hope that it will be useful,
    8.19 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.20 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    8.21 - * Lesser General Public License for more details.
    8.22 - * 
    8.23 - * You should have received a copy of the GNU Lesser General Public
    8.24 - * License along with this library; if not, write to the Free Software
    8.25 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
    8.26 - * 
    8.27 - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
    8.28 - * $/LicenseInfo$
    8.29 - * @endcond
    8.30 - */
    8.31 -
    8.32 -#include "linden_common.h"
    8.33 -#include <list>
    8.34 -#include "../test/lltut.h"
    8.35 -
    8.36 -#include "../llplugincookiestore.h"
    8.37 -
    8.38 -
    8.39 -namespace tut
    8.40 -{
    8.41 -	// Main Setup
    8.42 -	struct LLPluginCookieStoreFixture
    8.43 -	{
    8.44 -		LLPluginCookieStoreFixture()
    8.45 -		{
    8.46 -			// We need dates definitively in the past and the future to properly test cookie expiration.
    8.47 -			LLDate now = LLDate::now(); 
    8.48 -			LLDate past(now.secondsSinceEpoch() - (60.0 * 60.0 * 24.0));	// 1 day in the past
    8.49 -			LLDate future(now.secondsSinceEpoch() + (60.0 * 60.0 * 24.0));	// 1 day in the future
    8.50 -			
    8.51 -			mPastString = past.asRFC1123();
    8.52 -			mFutureString = future.asRFC1123();
    8.53 -		}
    8.54 -		
    8.55 -		std::string mPastString;
    8.56 -		std::string mFutureString;
    8.57 -		LLPluginCookieStore mCookieStore;
    8.58 -		
    8.59 -		// List of cookies used for validation
    8.60 -		std::list<std::string> mCookies;
    8.61 -		
    8.62 -		// This sets up mCookies from a string returned by one of the functions in LLPluginCookieStore
    8.63 -		void setCookies(const std::string &cookies)
    8.64 -		{
    8.65 -			mCookies.clear();
    8.66 -			std::string::size_type start = 0;
    8.67 -
    8.68 -			while(start != std::string::npos)
    8.69 -			{
    8.70 -				std::string::size_type end = cookies.find_first_of("\r\n", start);
    8.71 -				if(end > start)
    8.72 -				{
    8.73 -					std::string line(cookies, start, end - start);
    8.74 -					if(line.find_first_not_of("\r\n\t ") != std::string::npos)
    8.75 -					{
    8.76 -						// The line has some non-whitespace characters.  Save it to the list.
    8.77 -						mCookies.push_back(std::string(cookies, start, end - start));
    8.78 -					}
    8.79 -				}
    8.80 -				start = cookies.find_first_not_of("\r\n ", end);
    8.81 -			}
    8.82 -		}
    8.83 -		
    8.84 -		// This ensures that a cookie matching the one passed is in the list.
    8.85 -		void ensureCookie(const std::string &cookie)
    8.86 -		{
    8.87 -			std::list<std::string>::iterator iter;
    8.88 -			for(iter = mCookies.begin(); iter != mCookies.end(); iter++)
    8.89 -			{
    8.90 -				if(*iter == cookie)
    8.91 -				{
    8.92 -					// Found the cookie
    8.93 -					// TODO: this should do a smarter equality comparison on the two cookies, instead of just a string compare.
    8.94 -					return;
    8.95 -				}
    8.96 -			}
    8.97 -			
    8.98 -			// Didn't find this cookie
    8.99 -			std::string message = "cookie not found: ";
   8.100 -			message += cookie;
   8.101 -			ensure(message, false);
   8.102 -		}
   8.103 -		
   8.104 -		// This ensures that the number of cookies in the list matches what's expected.
   8.105 -		void ensureSize(const std::string &message, size_t size)
   8.106 -		{
   8.107 -			if(mCookies.size() != size)
   8.108 -			{
   8.109 -				std::stringstream full_message;
   8.110 -				
   8.111 -				full_message << message << " (expected " << size << ", actual " << mCookies.size() << ")";
   8.112 -				ensure(full_message.str(), false);
   8.113 -			}
   8.114 -		}
   8.115 -	};
   8.116 -	
   8.117 -	typedef test_group<LLPluginCookieStoreFixture> factory;
   8.118 -	typedef factory::object object;
   8.119 -	factory tf("LLPluginCookieStore");
   8.120 -
   8.121 -	// Tests
   8.122 -	template<> template<>
   8.123 -	void object::test<1>()
   8.124 -	{
   8.125 -		// Test 1: cookie uniqueness and update lists.
   8.126 -		// Valid, distinct cookies:
   8.127 -		
   8.128 -		std::string cookie01 = "cookieA=value; domain=example.com; path=/";
   8.129 -		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.
   8.130 -		std::string cookie03 = "cookieA=value; domain=foo.example.com; path=/"; // different domain
   8.131 -		std::string cookie04 = "cookieA=value; domain=example.com; path=/bar/"; // different path
   8.132 -		std::string cookie05 = "cookieC; domain=example.com; path=/"; // empty value
   8.133 -		std::string cookie06 = "cookieD=value; domain=example.com; path=/; expires="; // different name, persistent cookie
   8.134 -		cookie06 += mFutureString;
   8.135 -		
   8.136 -		mCookieStore.setCookies(cookie01);
   8.137 -		mCookieStore.setCookies(cookie02);
   8.138 -		mCookieStore.setCookies(cookie03);
   8.139 -		mCookieStore.setCookies(cookie04);
   8.140 -		mCookieStore.setCookies(cookie05);
   8.141 -		mCookieStore.setCookies(cookie06);
   8.142 -		
   8.143 -		// Invalid cookies (these will get parse errors and not be added to the store)
   8.144 -
   8.145 -		std::string badcookie01 = "cookieD=value; domain=example.com; path=/; foo=bar"; // invalid field name
   8.146 -		std::string badcookie02 = "cookieE=value; path=/"; // no domain
   8.147 -
   8.148 -		mCookieStore.setCookies(badcookie01);
   8.149 -		mCookieStore.setCookies(badcookie02);
   8.150 -		
   8.151 -		// All cookies added so far should have been marked as "changed"
   8.152 -		setCookies(mCookieStore.getChangedCookies());
   8.153 -		ensureSize("count of changed cookies", 6);
   8.154 -		ensureCookie(cookie01);
   8.155 -		ensureCookie(cookie02);
   8.156 -		ensureCookie(cookie03);
   8.157 -		ensureCookie(cookie04);
   8.158 -		ensureCookie(cookie05);
   8.159 -		ensureCookie(cookie06);
   8.160 -		
   8.161 -		// Save off the current state of the cookie store (we'll restore it later)
   8.162 -		std::string savedCookies = mCookieStore.getAllCookies();
   8.163 -		
   8.164 -		// Test replacing cookies
   8.165 -		std::string cookie01a = "cookieA=newvalue; domain=example.com; path=/";	// updated value
   8.166 -		std::string cookie02a = "cookieB=newvalue; domain=example.com; path=/; expires="; // remove cookie (by setting an expire date in the past)
   8.167 -		cookie02a += mPastString;
   8.168 -		
   8.169 -		mCookieStore.setCookies(cookie01a);
   8.170 -		mCookieStore.setCookies(cookie02a);
   8.171 -
   8.172 -		// test for getting changed cookies
   8.173 -		setCookies(mCookieStore.getChangedCookies());
   8.174 -		ensureSize("count of updated cookies", 2);
   8.175 -		ensureCookie(cookie01a);
   8.176 -		ensureCookie(cookie02a);
   8.177 -		
   8.178 -		// and for the state of the store after getting changed cookies
   8.179 -		setCookies(mCookieStore.getAllCookies());
   8.180 -		ensureSize("count of valid cookies", 5);
   8.181 -		ensureCookie(cookie01a);
   8.182 -		ensureCookie(cookie03);
   8.183 -		ensureCookie(cookie04);
   8.184 -		ensureCookie(cookie05);
   8.185 -		ensureCookie(cookie06);
   8.186 -
   8.187 -		// Check that only the persistent cookie is returned here
   8.188 -		setCookies(mCookieStore.getPersistentCookies());
   8.189 -		ensureSize("count of persistent cookies", 1);
   8.190 -		ensureCookie(cookie06);
   8.191 -
   8.192 -		// Restore the cookie store to a previous state and verify
   8.193 -		mCookieStore.setAllCookies(savedCookies);
   8.194 -		
   8.195 -		// Since setAllCookies defaults to not marking cookies as changed, this list should be empty.
   8.196 -		setCookies(mCookieStore.getChangedCookies());
   8.197 -		ensureSize("count of changed cookies after restore", 0);
   8.198 -
   8.199 -		// Verify that the restore worked as it should have.
   8.200 -		setCookies(mCookieStore.getAllCookies());
   8.201 -		ensureSize("count of restored cookies", 6);
   8.202 -		ensureCookie(cookie01);
   8.203 -		ensureCookie(cookie02);
   8.204 -		ensureCookie(cookie03);
   8.205 -		ensureCookie(cookie04);
   8.206 -		ensureCookie(cookie05);
   8.207 -		ensureCookie(cookie06);
   8.208 -	}
   8.209 -
   8.210 -}
     9.1 --- a/indra/media_plugins/cef/media_plugin_cef.cpp	Wed Feb 14 11:37:07 2018 +0200
     9.2 +++ b/indra/media_plugins/cef/media_plugin_cef.cpp	Wed Feb 14 21:56:53 2018 +0100
     9.3 @@ -38,6 +38,7 @@
     9.4  #include "media_plugin_base.h"
     9.5  
     9.6  #include <functional>
     9.7 +#include <chrono>
     9.8  
     9.9  #include "dullahan.h"
    9.10  
    9.11 @@ -64,12 +65,12 @@
    9.12  	void onLoadStartCallback();
    9.13  	void onRequestExitCallback();
    9.14  	void onLoadEndCallback(int httpStatusCode);
    9.15 +	void onLoadError(int status, const std::string error_text);
    9.16  	void onAddressChangeCallback(std::string url);
    9.17  	void onNavigateURLCallback(std::string url, std::string target);
    9.18  	bool onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password);
    9.19  	void onCursorChangedCallback(dullahan::ECursorType type);
    9.20 -	void onFileDownloadCallback(std::string filename);
    9.21 -	const std::string onFileDialogCallback();
    9.22 +	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);
    9.23  
    9.24  	void postDebugMessage(const std::string& msg);
    9.25  	void authResponse(LLPluginMessage &message);
    9.26 @@ -95,7 +96,9 @@
    9.27  	bool mCanPaste;
    9.28  	std::string mCachePath;
    9.29  	std::string mCookiePath;
    9.30 -	std::string mPickedFile;
    9.31 +	std::string mCefLogFile;
    9.32 +	bool mCefLogVerbose;
    9.33 +	std::vector<std::string> mPickedFiles;
    9.34  	VolumeCatcher mVolumeCatcher;
    9.35  	F32 mCurVolume;
    9.36  	dullahan* mCEFLib;
    9.37 @@ -115,7 +118,7 @@
    9.38  	mCookiesEnabled = true;
    9.39  	mPluginsEnabled = false;
    9.40  	mJavascriptEnabled = true;
    9.41 -	mDisableGPU = true;
    9.42 +	mDisableGPU = false;
    9.43  	mUserAgentSubtring = "";
    9.44  	mAuthUsername = "";
    9.45  	mAuthPassword = "";
    9.46 @@ -125,7 +128,9 @@
    9.47  	mCanPaste = false;
    9.48  	mCachePath = "";
    9.49  	mCookiePath = "";
    9.50 -	mPickedFile = "";
    9.51 +	mCefLogFile = "";
    9.52 +	mCefLogVerbose = false;
    9.53 +	mPickedFiles.clear();
    9.54  	mCurVolume = 0.0;
    9.55  
    9.56  	mCEFLib = new dullahan();
    9.57 @@ -166,6 +171,10 @@
    9.58  		{
    9.59  			memcpy(mPixels, pixels, mWidth * mHeight * mDepth);
    9.60  		}
    9.61 +		else
    9.62 +		{
    9.63 +			mCEFLib->setSize(mWidth, mHeight);
    9.64 +		}
    9.65  		setDirty(0, 0, mWidth, mHeight);
    9.66  	}
    9.67  }
    9.68 @@ -208,6 +217,21 @@
    9.69  	sendMessage(message);
    9.70  }
    9.71  
    9.72 +/////////////////////////////////////////////////////////////////////////////////
    9.73 +//
    9.74 +void MediaPluginCEF::onLoadError(int status, const std::string error_text)
    9.75 +{
    9.76 +	std::stringstream msg;
    9.77 +
    9.78 +	msg << "<b>Loading error!</b>";
    9.79 +	msg << "<p>";
    9.80 +	msg << "Message: " << error_text;
    9.81 +	msg << "<br>";
    9.82 +	msg << "Code: " << status;
    9.83 +
    9.84 +	mCEFLib->showBrowserMessage(msg.str());
    9.85 +}
    9.86 +
    9.87  ////////////////////////////////////////////////////////////////////////////////
    9.88  //
    9.89  void MediaPluginCEF::onRequestExitCallback()
    9.90 @@ -246,7 +270,6 @@
    9.91  	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_href");
    9.92  	message.setValue("uri", url);
    9.93  	message.setValue("target", target);
    9.94 -	message.setValue("uuid", "");	// not used right now
    9.95  	sendMessage(message);
    9.96  }
    9.97  
    9.98 @@ -285,30 +308,52 @@
    9.99  
   9.100  ////////////////////////////////////////////////////////////////////////////////
   9.101  //
   9.102 -void MediaPluginCEF::onFileDownloadCallback(const std::string filename)
   9.103 +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)
   9.104  {
   9.105 -	mAuthOK = false;
   9.106 +	// do not use the default CEF file picker
   9.107 +	use_default = false;
   9.108  
   9.109 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "file_download");
   9.110 -	message.setValue("filename", filename);
   9.111 +	if (dialog_type == dullahan::FD_OPEN_FILE)
   9.112 +	{
   9.113 +		mPickedFiles.clear();
   9.114  
   9.115 -	sendMessage(message);
   9.116 +		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file");
   9.117 +		message.setValueBoolean("blocking_request", true);
   9.118 +		message.setValueBoolean("multiple_files", false);
   9.119 +
   9.120 +		sendMessage(message);
   9.121 +
   9.122 +		return mPickedFiles;
   9.123 +	}
   9.124 +	else if (dialog_type == dullahan::FD_OPEN_MULTIPLE_FILES)
   9.125 +	{
   9.126 +		mPickedFiles.clear();
   9.127 +
   9.128 +		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file");
   9.129 +		message.setValueBoolean("blocking_request", true);
   9.130 +		message.setValueBoolean("multiple_files", true);
   9.131 +
   9.132 +		sendMessage(message);
   9.133 +
   9.134 +		return mPickedFiles;
   9.135 +	}
   9.136 +	else if (dialog_type == dullahan::FD_SAVE_FILE)
   9.137 +	{
   9.138 +		mAuthOK = false;
   9.139 +
   9.140 +		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "file_download");
   9.141 +		message.setValue("filename", default_file);
   9.142 +
   9.143 +		sendMessage(message);
   9.144 +
   9.145 +		return std::vector<std::string>();
   9.146 +	}
   9.147 +
   9.148 +	return std::vector<std::string>();
   9.149  }
   9.150  
   9.151  ////////////////////////////////////////////////////////////////////////////////
   9.152  //
   9.153 -const std::string MediaPluginCEF::onFileDialogCallback()
   9.154 -{
   9.155 -	mPickedFile.clear();
   9.156 -
   9.157 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file");
   9.158 -	message.setValueBoolean("blocking_request", true);
   9.159 -
   9.160 -	sendMessage(message);
   9.161 -
   9.162 -	return mPickedFile;
   9.163 -}
   9.164 -
   9.165  void MediaPluginCEF::onCursorChangedCallback(dullahan::ECursorType type)
   9.166  {
   9.167  	std::string name = "";
   9.168 @@ -341,6 +386,8 @@
   9.169  	sendMessage(message);
   9.170  }
   9.171  
   9.172 +////////////////////////////////////////////////////////////////////////////////
   9.173 +//
   9.174  void MediaPluginCEF::authResponse(LLPluginMessage &message)
   9.175  {
   9.176  	mAuthOK = message.getValueBoolean("ok");
   9.177 @@ -373,7 +420,7 @@
   9.178  				versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION;
   9.179  				message.setValueLLSD("versions", versions);
   9.180  
   9.181 -				std::string plugin_version = "CEF plugin 1.1.3";
   9.182 +				std::string plugin_version = "CEF plugin 1.1.412";
   9.183  				message.setValue("plugin_version", plugin_version);
   9.184  				sendMessage(message);
   9.185  			}
   9.186 @@ -439,11 +486,11 @@
   9.187  				mCEFLib->setOnTitleChangeCallback(std::bind(&MediaPluginCEF::onTitleChangeCallback, this, std::placeholders::_1));
   9.188  				mCEFLib->setOnLoadStartCallback(std::bind(&MediaPluginCEF::onLoadStartCallback, this));
   9.189  				mCEFLib->setOnLoadEndCallback(std::bind(&MediaPluginCEF::onLoadEndCallback, this, std::placeholders::_1));
   9.190 +				mCEFLib->setOnLoadErrorCallback(std::bind(&MediaPluginCEF::onLoadError, this, std::placeholders::_1, std::placeholders::_2));
   9.191  				mCEFLib->setOnAddressChangeCallback(std::bind(&MediaPluginCEF::onAddressChangeCallback, this, std::placeholders::_1));
   9.192  				mCEFLib->setOnNavigateURLCallback(std::bind(&MediaPluginCEF::onNavigateURLCallback, this, std::placeholders::_1, std::placeholders::_2));
   9.193  				mCEFLib->setOnHTTPAuthCallback(std::bind(&MediaPluginCEF::onHTTPAuthCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
   9.194 -				mCEFLib->setOnFileDownloadCallback(std::bind(&MediaPluginCEF::onFileDownloadCallback, this, std::placeholders::_1));
   9.195 -				mCEFLib->setOnFileDialogCallback(std::bind(&MediaPluginCEF::onFileDialogCallback, this));
   9.196 +				mCEFLib->setOnFileDialogCallback(std::bind(&MediaPluginCEF::onFileDialog, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
   9.197  				mCEFLib->setOnCursorChangedCallback(std::bind(&MediaPluginCEF::onCursorChangedCallback, this, std::placeholders::_1));
   9.198  				mCEFLib->setOnRequestExitCallback(std::bind(&MediaPluginCEF::onRequestExitCallback, this));
   9.199  
   9.200 @@ -468,6 +515,8 @@
   9.201  				settings.plugins_enabled = mPluginsEnabled;
   9.202  				settings.user_agent_substring = mCEFLib->makeCompatibleUserAgentString(mUserAgentSubtring);
   9.203  				settings.webgl_enabled = true;
   9.204 +				settings.log_file = mCefLogFile;
   9.205 +				settings.log_verbose = mCefLogVerbose;
   9.206  
   9.207  				std::vector<std::string> custom_schemes(1, "secondlife");
   9.208  				mCEFLib->setCustomSchemes(custom_schemes);
   9.209 @@ -497,8 +546,11 @@
   9.210  			{
   9.211  				std::string user_data_path_cache = message_in.getValue("cache_path");
   9.212  				std::string user_data_path_cookies = message_in.getValue("cookies_path");
   9.213 +
   9.214  				mCachePath = user_data_path_cache + "cef_cache";
   9.215  				mCookiePath = user_data_path_cookies + "cef_cookies";
   9.216 +				mCefLogFile = message_in.getValue("cef_log_file");
   9.217 +				mCefLogVerbose = message_in.getValueBoolean("cef_verbose_log");
   9.218  			}
   9.219  			else if (message_name == "size_change")
   9.220  			{
   9.221 @@ -520,11 +572,11 @@
   9.222  
   9.223  						mTextureWidth = texture_width;
   9.224  						mTextureHeight = texture_height;
   9.225 +
   9.226 +						mCEFLib->setSize(mWidth, mHeight);
   9.227  					};
   9.228  				};
   9.229  
   9.230 -				mCEFLib->setSize(mWidth, mHeight);
   9.231 -
   9.232  				LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
   9.233  				message.setValue("name", name);
   9.234  				message.setValueS32("width", width);
   9.235 @@ -651,7 +703,14 @@
   9.236  			}
   9.237  			if (message_name == "pick_file_response")
   9.238  			{
   9.239 -				mPickedFile = message_in.getValue("file");
   9.240 +				LLSD file_list_llsd = message_in.getValueLLSD("file_list");
   9.241 +
   9.242 +				LLSD::array_const_iterator iter = file_list_llsd.beginArray();
   9.243 +				LLSD::array_const_iterator end = file_list_llsd.endArray();
   9.244 +				for (; iter != end; ++iter)
   9.245 +				{
   9.246 +					mPickedFiles.push_back(((*iter).asString()));
   9.247 +				}
   9.248  			}
   9.249  			if (message_name == "auth_response")
   9.250  			{
   9.251 @@ -698,6 +757,10 @@
   9.252  			{
   9.253  				mCookiesEnabled = message_in.getValueBoolean("enable");
   9.254  			}
   9.255 +			else if (message_name == "clear_cookies")
   9.256 +			{
   9.257 +				mCEFLib->deleteAllCookies();
   9.258 +			}
   9.259  			else if (message_name == "set_user_agent")
   9.260  			{
   9.261  				mUserAgentSubtring = message_in.getValue("user_agent");
    10.1 --- a/indra/newview/app_settings/settings.xml	Wed Feb 14 11:37:07 2018 +0200
    10.2 +++ b/indra/newview/app_settings/settings.xml	Wed Feb 14 21:56:53 2018 +0100
    10.3 @@ -21003,6 +21003,17 @@
    10.4        <key>Value</key>
    10.5        <integer>0</integer>
    10.6      </map>
    10.7 +    <key>CefVerboseLog</key>
    10.8 +    <map>
    10.9 +      <key>Comment</key>
   10.10 +      <string>Enable/disable CEF verbose loggingk</string>
   10.11 +      <key>Persist</key>
   10.12 +      <integer>1</integer>
   10.13 +      <key>Type</key>
   10.14 +      <string>Boolean</string>
   10.15 +      <key>Value</key>
   10.16 +      <integer>0</integer>
   10.17 +    </map>
   10.18      <key>FSShowServerVersionChangeNotice</key>
   10.19      <map>
   10.20        <key>Comment</key>
    11.1 --- a/indra/newview/llappviewer.cpp	Wed Feb 14 11:37:07 2018 +0200
    11.2 +++ b/indra/newview/llappviewer.cpp	Wed Feb 14 21:56:53 2018 +0100
    11.3 @@ -2307,8 +2307,6 @@
    11.4  
    11.5  	LLAvatarIconIDCache::getInstance()->save();
    11.6  	
    11.7 -	LLViewerMedia::saveCookieFile();
    11.8 -
    11.9  	// Stop the plugin read thread if it's running.
   11.10  	LLPluginProcessParent::setUseReadThread(false);
   11.11  
   11.12 @@ -3824,8 +3822,14 @@
   11.13  	cef_ver_codec << " / CEF: ";
   11.14  	cef_ver_codec << CEF_VERSION;
   11.15  
   11.16 -	cef_ver_codec << " / Chrome: ";
   11.17 +	cef_ver_codec << " / Chromium: ";
   11.18  	cef_ver_codec << CHROME_VERSION_MAJOR;
   11.19 +	cef_ver_codec << ".";
   11.20 +	cef_ver_codec << CHROME_VERSION_MINOR;
   11.21 +	cef_ver_codec << ".";
   11.22 +	cef_ver_codec << CHROME_VERSION_BUILD;
   11.23 +	cef_ver_codec << ".";
   11.24 +	cef_ver_codec << CHROME_VERSION_PATCH;
   11.25  
   11.26  	info["LIBCEF_VERSION"] = cef_ver_codec.str();
   11.27  //#else
    12.1 --- a/indra/newview/llfloaterfacebook.cpp	Wed Feb 14 11:37:07 2018 +0200
    12.2 +++ b/indra/newview/llfloaterfacebook.cpp	Wed Feb 14 21:56:53 2018 +0100
    12.3 @@ -1,4 +1,4 @@
    12.4 -/** 
    12.5 +/**
    12.6  * @file llfloaterfacebook.cpp
    12.7  * @brief Implementation of llfloaterfacebook
    12.8  * @author Gilbert@lindenlab.com
    12.9 @@ -41,7 +41,6 @@
   12.10  #include "llresmgr.h"		// LLLocale
   12.11  #include "llsdserialize.h"
   12.12  #include "llloadingindicator.h"
   12.13 -#include "llplugincookiestore.h"
   12.14  #include "llslurl.h"
   12.15  #include "lltrans.h"
   12.16  #include "llsnapshotlivepreview.h"
   12.17 @@ -303,16 +302,11 @@
   12.18  void LLFacebookStatusPanel::onConnect()
   12.19  {
   12.20      LLFacebookConnect::instance().checkConnectionToFacebook(true);
   12.21 -
   12.22 -    //Clear only the facebook browser cookies so that the facebook login screen appears
   12.23 -    LLViewerMedia::getCookieStore()->removeCookiesByDomain(".facebook.com");
   12.24  }
   12.25  
   12.26  void LLFacebookStatusPanel::onDisconnect()
   12.27  {
   12.28      LLFacebookConnect::instance().disconnectFromFacebook();
   12.29 -
   12.30 -    LLViewerMedia::getCookieStore()->removeCookiesByDomain(".facebook.com");
   12.31  }
   12.32  
   12.33  void LLFacebookStatusPanel::clearAndClose()
   12.34 @@ -914,7 +908,7 @@
   12.35      LLAgentUI::buildSLURL(slurl);
   12.36      std::string slurl_string = slurl.getSLURLString();
   12.37  
   12.38 -    // Use a valid http:// URL if the scheme is secondlife:// 
   12.39 +    // Use a valid http:// URL if the scheme is secondlife://
   12.40      LLURI slurl_uri(slurl_string);
   12.41      if (slurl_uri.scheme() == LLSLURL::SLURL_SECONDLIFE_SCHEME)
   12.42      {
    13.1 --- a/indra/newview/llfloaterflickr.cpp	Wed Feb 14 11:37:07 2018 +0200
    13.2 +++ b/indra/newview/llfloaterflickr.cpp	Wed Feb 14 21:56:53 2018 +0100
    13.3 @@ -40,7 +40,6 @@
    13.4  #include "llresmgr.h"		// LLLocale
    13.5  #include "llsdserialize.h"
    13.6  #include "llloadingindicator.h"
    13.7 -#include "llplugincookiestore.h"
    13.8  #include "llslurl.h"
    13.9  #include "lltrans.h"
   13.10  #include "llsnapshotlivepreview.h"
   13.11 @@ -889,16 +888,11 @@
   13.12  void LLFlickrAccountPanel::onConnect()
   13.13  {
   13.14  	LLFlickrConnect::instance().checkConnectionToFlickr(true);
   13.15 -
   13.16 -	//Clear only the flickr browser cookies so that the flickr login screen appears
   13.17 -	LLViewerMedia::getCookieStore()->removeCookiesByDomain(".flickr.com"); 
   13.18  }
   13.19  
   13.20  void LLFlickrAccountPanel::onDisconnect()
   13.21  {
   13.22  	LLFlickrConnect::instance().disconnectFromFlickr();
   13.23 -
   13.24 -	LLViewerMedia::getCookieStore()->removeCookiesByDomain(".flickr.com"); 
   13.25  }
   13.26  
   13.27  ////////////////////////
    14.1 --- a/indra/newview/llfloatertwitter.cpp	Wed Feb 14 11:37:07 2018 +0200
    14.2 +++ b/indra/newview/llfloatertwitter.cpp	Wed Feb 14 21:56:53 2018 +0100
    14.3 @@ -41,7 +41,6 @@
    14.4  #include "llresmgr.h"		// LLLocale
    14.5  #include "llsdserialize.h"
    14.6  #include "llloadingindicator.h"
    14.7 -#include "llplugincookiestore.h"
    14.8  #include "llslurl.h"
    14.9  #include "lltrans.h"
   14.10  #include "llsnapshotlivepreview.h"
   14.11 @@ -782,16 +781,11 @@
   14.12  void LLTwitterAccountPanel::onConnect()
   14.13  {
   14.14  	LLTwitterConnect::instance().checkConnectionToTwitter(true);
   14.15 -
   14.16 -	//Clear only the twitter browser cookies so that the twitter login screen appears
   14.17 -	LLViewerMedia::getCookieStore()->removeCookiesByDomain(".twitter.com"); 
   14.18  }
   14.19  
   14.20  void LLTwitterAccountPanel::onDisconnect()
   14.21  {
   14.22  	LLTwitterConnect::instance().disconnectFromTwitter();
   14.23 -
   14.24 -	LLViewerMedia::getCookieStore()->removeCookiesByDomain(".twitter.com"); 
   14.25  }
   14.26  
   14.27  ////////////////////////
    15.1 --- a/indra/newview/llmediactrl.cpp	Wed Feb 14 11:37:07 2018 +0200
    15.2 +++ b/indra/newview/llmediactrl.cpp	Wed Feb 14 21:56:53 2018 +0100
    15.3 @@ -1082,7 +1082,7 @@
    15.4  			// try as slurl first
    15.5  			if (!LLURLDispatcher::dispatch(url, "clicked", NULL, mTrusted))
    15.6  			{
    15.7 -				LLWeb::loadURL(url, target, std::string());
    15.8 +				LLWeb::loadURL(url, target, uuid);
    15.9  			}
   15.10  
   15.11  			// CP: removing this code because we no longer support popups so this breaks the flow.
    16.1 --- a/indra/newview/llstartup.cpp	Wed Feb 14 11:37:07 2018 +0200
    16.2 +++ b/indra/newview/llstartup.cpp	Wed Feb 14 21:56:53 2018 +0100
    16.3 @@ -1505,9 +1505,6 @@
    16.4  		// Load Avatars icons cache
    16.5  		LLAvatarIconIDCache::getInstance()->load();
    16.6  		
    16.7 -		// Load media plugin cookies
    16.8 -		LLViewerMedia::loadCookieFile();
    16.9 -
   16.10  		// <FS:Ansariel> [FS Persisted Avatar Render Settings]
   16.11  		//LLRenderMuteList::getInstance()->loadFromFile();
   16.12  
    17.1 --- a/indra/newview/llviewermedia.cpp	Wed Feb 14 11:37:07 2018 +0200
    17.2 +++ b/indra/newview/llviewermedia.cpp	Wed Feb 14 21:56:53 2018 +0100
    17.3 @@ -50,7 +50,6 @@
    17.4  #include "llpanelprofile.h"
    17.5  #include "llparcel.h"
    17.6  #include "llpluginclassmedia.h"
    17.7 -#include "llplugincookiestore.h"
    17.8  #include "llurldispatcher.h"
    17.9  #include "lluuid.h"
   17.10  #include "llversioninfo.h"
   17.11 @@ -154,7 +153,6 @@
   17.12  }
   17.13  
   17.14  
   17.15 -LLPluginCookieStore *LLViewerMedia::sCookieStore = NULL;
   17.16  LLURL LLViewerMedia::sOpenIDURL;
   17.17  std::string LLViewerMedia::sOpenIDCookie;
   17.18  LLPluginClassMedia* LLViewerMedia::sSpareBrowserMediaSource = NULL;
   17.19 @@ -169,8 +167,6 @@
   17.20  static bool sAnyMediaShowing = false;
   17.21  static bool sAnyMediaPlaying = false;
   17.22  static boost::signals2::connection sTeleportFinishConnection;
   17.23 -static std::string sUpdatedCookies;
   17.24 -static const char *PLUGIN_COOKIE_FILE_NAME = "plugin_cookies.txt";
   17.25  
   17.26  //////////////////////////////////////////////////////////////////////////////////////////
   17.27  static void add_media_impl(LLViewerMediaImpl* media)
   17.28 @@ -614,12 +610,6 @@
   17.29  
   17.30  	sAnyMediaShowing = false;
   17.31  	sAnyMediaPlaying = false;
   17.32 -	sUpdatedCookies = getCookieStore()->getChangedCookies();
   17.33 -	if(!sUpdatedCookies.empty())
   17.34 -	{
   17.35 -		LL_DEBUGS() << "updated cookies will be sent to all loaded plugins: " << LL_ENDL;
   17.36 -		LL_DEBUGS() << sUpdatedCookies << LL_ENDL;
   17.37 -	}
   17.38  
   17.39  	impl_list::iterator iter = sViewerMediaImplList.begin();
   17.40  	impl_list::iterator end = sViewerMediaImplList.end();
   17.41 @@ -1076,64 +1066,6 @@
   17.42  			pimpl->mMediaSource->clear_cookies();
   17.43  		}
   17.44  	}
   17.45 -
   17.46 -	// Clear all cookies from the cookie store
   17.47 -	getCookieStore()->setAllCookies("");
   17.48 -
   17.49 -	// FIXME: this may not be sufficient, since the on-disk cookie file won't get written until some browser instance exits cleanly.
   17.50 -	// 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.
   17.51 -	// Until such time as we can centralize cookie storage, the following hack should cover these cases:
   17.52 -
   17.53 -	// HACK: Look for cookie files in all possible places and delete them.
   17.54 -	// 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)
   17.55 -
   17.56 -	// Places that cookie files can be:
   17.57 -	// <getOSUserAppDir>/browser_profile/cookies
   17.58 -	// <getOSUserAppDir>/first_last/browser_profile/cookies  (note that there may be any number of these!)
   17.59 -	// <getOSUserAppDir>/first_last/plugin_cookies.txt  (note that there may be any number of these!)
   17.60 -
   17.61 -	std::string base_dir = gDirUtilp->getOSUserAppDir() + gDirUtilp->getDirDelimiter();
   17.62 -	std::string target;
   17.63 -	std::string filename;
   17.64 -
   17.65 -	LL_DEBUGS() << "base dir = " << base_dir << LL_ENDL;
   17.66 -
   17.67 -	// The non-logged-in version is easy
   17.68 -	target = base_dir;
   17.69 -	target += "browser_profile";
   17.70 -	target += gDirUtilp->getDirDelimiter();
   17.71 -	target += "cookies";
   17.72 -	LL_DEBUGS() << "target = " << target << LL_ENDL;
   17.73 -	if(LLFile::isfile(target))
   17.74 -	{
   17.75 -		LLFile::remove(target);
   17.76 -	}
   17.77 -
   17.78 -	// the hard part: iterate over all user directories and delete the cookie file from each one
   17.79 -	LLDirIterator dir_iter(base_dir, "*_*");
   17.80 -	while (dir_iter.next(filename))
   17.81 -	{
   17.82 -		target = gDirUtilp->add(base_dir, filename);
   17.83 -		gDirUtilp->append(target, "browser_profile");
   17.84 -		gDirUtilp->append(target, "cookies");
   17.85 -		LL_DEBUGS() << "target = " << target << LL_ENDL;
   17.86 -		if(LLFile::isfile(target))
   17.87 -		{
   17.88 -			LLFile::remove(target);
   17.89 -		}
   17.90 -
   17.91 -		// Other accounts may have new-style cookie files too -- delete them as well
   17.92 -		target = gDirUtilp->add(base_dir, filename);
   17.93 -		gDirUtilp->append(target, PLUGIN_COOKIE_FILE_NAME);
   17.94 -		LL_DEBUGS() << "target = " << target << LL_ENDL;
   17.95 -		if(LLFile::isfile(target))
   17.96 -		{
   17.97 -			LLFile::remove(target);
   17.98 -		}
   17.99 -	}
  17.100 -
  17.101 -	// If we have an OpenID cookie, re-add it to the cookie store.
  17.102 -	setOpenIDCookie(std::string());
  17.103  }
  17.104  
  17.105  /////////////////////////////////////////////////////////////////////////////////////////
  17.106 @@ -1162,7 +1094,7 @@
  17.107  		LLViewerMediaImpl* pimpl = *iter;
  17.108  		if(pimpl->mMediaSource)
  17.109  		{
  17.110 -			pimpl->mMediaSource->enable_cookies(enabled);
  17.111 +			pimpl->mMediaSource->cookies_enabled(enabled);
  17.112  		}
  17.113  	}
  17.114  }
  17.115 @@ -1187,127 +1119,7 @@
  17.116  /////////////////////////////////////////////////////////////////////////////////////////
  17.117  // static
  17.118  /////////////////////////////////////////////////////////////////////////////////////////
  17.119 -// static
  17.120 -LLPluginCookieStore *LLViewerMedia::getCookieStore()
  17.121 -{
  17.122 -	if(sCookieStore == NULL)
  17.123 -	{
  17.124 -		sCookieStore = new LLPluginCookieStore;
  17.125 -	}
  17.126 -
  17.127 -	return sCookieStore;
  17.128 -}
  17.129 -
  17.130 -/////////////////////////////////////////////////////////////////////////////////////////
  17.131 -// static
  17.132 -void LLViewerMedia::loadCookieFile()
  17.133 -{
  17.134 -	// build filename for each user
  17.135 -	std::string resolved_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PLUGIN_COOKIE_FILE_NAME);
  17.136 -
  17.137 -	if (resolved_filename.empty())
  17.138 -	{
  17.139 -		LL_INFOS() << "can't get path to plugin cookie file - probably not logged in yet." << LL_ENDL;
  17.140 -		return;
  17.141 -	}
  17.142 -
  17.143 -	// open the file for reading
  17.144 -	llifstream file(resolved_filename.c_str());
  17.145 -	if (!file.is_open())
  17.146 -	{
  17.147 -		LL_WARNS() << "can't load plugin cookies from file \"" << PLUGIN_COOKIE_FILE_NAME << "\"" << LL_ENDL;
  17.148 -		return;
  17.149 -	}
  17.150 -
  17.151 -	getCookieStore()->readAllCookies(file, true);
  17.152 -
  17.153 -	file.close();
  17.154 -
  17.155 -	// send the clear_cookies message to all loaded plugins
  17.156 -	impl_list::iterator iter = sViewerMediaImplList.begin();
  17.157 -	impl_list::iterator end = sViewerMediaImplList.end();
  17.158 -	for (; iter != end; iter++)
  17.159 -	{
  17.160 -		LLViewerMediaImpl* pimpl = *iter;
  17.161 -		if(pimpl->mMediaSource)
  17.162 -		{
  17.163 -			pimpl->mMediaSource->clear_cookies();
  17.164 -		}
  17.165 -	}
  17.166 -
  17.167 -	// If we have an OpenID cookie, re-add it to the cookie store.
  17.168 -	setOpenIDCookie(std::string());
  17.169 -}
  17.170 -
  17.171 -
  17.172 -/////////////////////////////////////////////////////////////////////////////////////////
  17.173 -// static
  17.174 -void LLViewerMedia::saveCookieFile()
  17.175 -{
  17.176 -	// build filename for each user
  17.177 -	std::string resolved_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PLUGIN_COOKIE_FILE_NAME);
  17.178 -
  17.179 -	if (resolved_filename.empty())
  17.180 -	{
  17.181 -		LL_INFOS() << "can't get path to plugin cookie file - probably not logged in yet." << LL_ENDL;
  17.182 -		return;
  17.183 -	}
  17.184 -
  17.185 -	// open a file for writing
  17.186 -	llofstream file(resolved_filename.c_str());
  17.187 -	if (!file.is_open())
  17.188 -	{
  17.189 -		LL_WARNS() << "can't open plugin cookie file \"" << PLUGIN_COOKIE_FILE_NAME << "\" for writing" << LL_ENDL;
  17.190 -		return;
  17.191 -	}
  17.192 -
  17.193 -	getCookieStore()->writePersistentCookies(file);
  17.194 -
  17.195 -	file.close();
  17.196 -}
  17.197 -
  17.198 -/////////////////////////////////////////////////////////////////////////////////////////
  17.199 -// static
  17.200 -void LLViewerMedia::addCookie(const std::string &name, const std::string &value, const std::string &domain, const LLDate &expires, const std::string &path, bool secure)
  17.201 -{
  17.202 -	std::stringstream cookie;
  17.203 -
  17.204 -	cookie << name << "=" << LLPluginCookieStore::quoteString(value);
  17.205 -
  17.206 -	if(expires.notNull())
  17.207 -	{
  17.208 -		cookie << "; expires=" << expires.asRFC1123();
  17.209 -	}
  17.210 -
  17.211 -	cookie << "; domain=" << domain;
  17.212 -
  17.213 -	cookie << "; path=" << path;
  17.214 -
  17.215 -	if(secure)
  17.216 -	{
  17.217 -		cookie << "; secure";
  17.218 -	}
  17.219 -
  17.220 -	getCookieStore()->setCookies(cookie.str());
  17.221 -}
  17.222 -
  17.223 -/////////////////////////////////////////////////////////////////////////////////////////
  17.224 -// static
  17.225 -void LLViewerMedia::addSessionCookie(const std::string &name, const std::string &value, const std::string &domain, const std::string &path, bool secure)
  17.226 -{
  17.227 -	// A session cookie just has a NULL date.
  17.228 -	addCookie(name, value, domain, LLDate(), path, secure);
  17.229 -}
  17.230 -
  17.231 -/////////////////////////////////////////////////////////////////////////////////////////
  17.232 -// static
  17.233 -void LLViewerMedia::removeCookie(const std::string &name, const std::string &domain, const std::string &path )
  17.234 -{
  17.235 -	// To remove a cookie, add one with the same name, domain, and path that expires in the past.
  17.236 -
  17.237 -	addCookie(name, "", domain, LLDate(LLDate::now().secondsSinceEpoch() - 1.0), path);
  17.238 -}
  17.239 -
  17.240 +//// static
  17.241  
  17.242  LLSD LLViewerMedia::getHeaders()
  17.243  {
  17.244 @@ -1412,8 +1224,6 @@
  17.245          hostEnd = authority.size();
  17.246      }
  17.247  
  17.248 -    getCookieStore()->setCookiesFromHost(sOpenIDCookie, authority.substr(hostStart, hostEnd - hostStart));
  17.249 -
  17.250  	if (url.length())
  17.251  	{
  17.252  		LLMediaCtrl* media_instance = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("destination_guide_contents");
  17.253 @@ -1451,7 +1261,6 @@
  17.254      httpHeaders->append(HTTP_OUT_HEADER_COOKIE, sOpenIDCookie);
  17.255      httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, getCurrentUserAgent());
  17.256  
  17.257 -
  17.258      LL_DEBUGS("MediaAuth") << "Requesting " << url << LL_ENDL;
  17.259      LL_DEBUGS("MediaAuth") << "sOpenIDCookie = [" << sOpenIDCookie << "]" << LL_ENDL;
  17.260      
  17.261 @@ -1476,13 +1285,9 @@
  17.262      const std::string& cookie = resultHeaders[HTTP_IN_HEADER_SET_COOKIE].asStringRef();
  17.263      LL_DEBUGS("MediaAuth") << "cookie = " << cookie << LL_ENDL;
  17.264  
  17.265 -    // *TODO: What about bad status codes?  Does this destroy previous cookies?
  17.266 -    LLViewerMedia::getCookieStore()->setCookiesFromHost(cookie, hostAuth);
  17.267 -
  17.268      // Set cookie for snapshot publishing.
  17.269      std::string authCookie = cookie.substr(0, cookie.find(";")); // strip path
  17.270      LLWebProfile::setAuthCookie(authCookie);
  17.271 -
  17.272  }
  17.273  
  17.274  /////////////////////////////////////////////////////////////////////////////////////////
  17.275 @@ -1677,12 +1482,6 @@
  17.276  		delete sSpareBrowserMediaSource;
  17.277  		sSpareBrowserMediaSource = NULL;
  17.278  	}
  17.279 -
  17.280 -	if (sCookieStore != NULL)
  17.281 -	{
  17.282 -		delete sCookieStore;
  17.283 -		sCookieStore = NULL;
  17.284 -	}
  17.285  }
  17.286  
  17.287  //////////////////////////////////////////////////////////////////////////////////////////
  17.288 @@ -1932,6 +1731,8 @@
  17.289  		std::string user_data_path_cookies = gDirUtilp->getOSUserAppDir();
  17.290  		user_data_path_cookies += gDirUtilp->getDirDelimiter();
  17.291  
  17.292 +		std::string user_data_path_cef_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "cef_log.txt");
  17.293 +
  17.294  		// Fix for EXT-5960 - make browser profile specific to user (cache, cookies etc.)
  17.295  		// If the linden username returned is blank, that can only mean we are
  17.296  		// at the login page displaying login Web page or Web browser test via Develop menu.
  17.297 @@ -1940,7 +1741,6 @@
  17.298  		std::string linden_user_dir = gDirUtilp->getLindenUserDir();
  17.299  		if ( ! linden_user_dir.empty() )
  17.300  		{
  17.301 -			// gDirUtilp->getLindenUserDir() is whole path, not just Linden name
  17.302  			user_data_path_cookies = linden_user_dir;
  17.303  			user_data_path_cookies += gDirUtilp->getDirDelimiter();
  17.304  		};
  17.305 @@ -1961,13 +1761,13 @@
  17.306  		{
  17.307  			media_source = new LLPluginClassMedia(owner);
  17.308  			media_source->setSize(default_width, default_height);
  17.309 -			media_source->setUserDataPath(user_data_path_cache, user_data_path_cookies);
  17.310 +			media_source->setUserDataPath(user_data_path_cache, user_data_path_cookies, user_data_path_cef_log);
  17.311  			media_source->setLanguageCode(LLUI::getLanguage());
  17.312  			media_source->setZoomFactor(zoom_factor);
  17.313  
  17.314  			// collect 'cookies enabled' setting from prefs and send to embedded browser
  17.315  			bool cookies_enabled = gSavedSettings.getBOOL( "CookiesEnabled" );
  17.316 -			media_source->enable_cookies( cookies_enabled || clean_browser);
  17.317 +			media_source->cookies_enabled( cookies_enabled || clean_browser);
  17.318  
  17.319  			// collect 'plugins enabled' setting from prefs and send to embedded browser
  17.320  			bool plugins_enabled = gSavedSettings.getBOOL( "BrowserPluginsEnabled" );
  17.321 @@ -2074,17 +1874,6 @@
  17.322  			media_source->clear_cache();
  17.323  		}
  17.324  
  17.325 -		// TODO: Only send cookies to plugins that need them
  17.326 -		//  Ideally, the plugin should tell us whether it handles cookies or not -- either via the init response or through a separate message.
  17.327 -		//  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,
  17.328 -		//  which could cause odd race conditions.
  17.329 -		std::string all_cookies = LLViewerMedia::getCookieStore()->getAllCookies();
  17.330 -		LL_DEBUGS() << "setting cookies: " << all_cookies << LL_ENDL;
  17.331 -		if(!all_cookies.empty())
  17.332 -		{
  17.333 -			media_source->set_cookies(all_cookies);
  17.334 -		}
  17.335 -
  17.336  		mMediaSource = media_source;
  17.337  		mMediaSource->setDeleteOK(false) ;
  17.338  		updateVolume();
  17.339 @@ -3044,14 +2833,10 @@
  17.340  		updateVolume();
  17.341  
  17.342  		// TODO: this is updated every frame - is this bad?
  17.343 -		updateJavascriptObject();
  17.344 -
  17.345 -		// If we didn't just create the impl, it may need to get cookie updates.
  17.346 -		if(!sUpdatedCookies.empty())
  17.347 -		{
  17.348 -			// TODO: Only send cookies to plugins that need them
  17.349 -			mMediaSource->set_cookies(sUpdatedCookies);
  17.350 -		}
  17.351 +		// Removing this as part of the post viewer64 media update
  17.352 +		// Removed as not implemented in CEF embedded browser
  17.353 +		// See MAINT-8194 for a more fuller description
  17.354 +		// updateJavascriptObject();
  17.355  	}
  17.356  
  17.357  
  17.358 @@ -3544,22 +3329,40 @@
  17.359  
  17.360  		case LLViewerMediaObserver::MEDIA_EVENT_PICK_FILE_REQUEST:
  17.361  		{
  17.362 -			// Display a file picker
  17.363 -			std::string response;
  17.364 -
  17.365  			LLFilePicker& picker = LLFilePicker::instance();
  17.366 -			if (!picker.getOpenFile(LLFilePicker::FFLOAD_ALL))
  17.367 +			std::vector<std::string> responses;
  17.368 +
  17.369 +			bool pick_multiple_files = plugin->getIsMultipleFilePick();
  17.370 +			if (pick_multiple_files == false)
  17.371  			{
  17.372 -				// The user didn't pick a file -- the empty response string will indicate this.
  17.373 +				picker.getOpenFile(LLFilePicker::FFLOAD_ALL);
  17.374 +
  17.375 +				std::string filename = picker.getFirstFile();
  17.376 +				responses.push_back(filename);
  17.377  			}
  17.378 -
  17.379 -			response = picker.getFirstFile();
  17.380 -
  17.381 -			plugin->sendPickFileResponse(response);
  17.382 +			else
  17.383 +			{
  17.384 +				if (picker.getMultipleOpenFiles())
  17.385 +				{
  17.386 +					std::string filename = picker.getFirstFile();
  17.387 +
  17.388 +					responses.push_back(filename);
  17.389 +
  17.390 +					while (!filename.empty())
  17.391 +					{
  17.392 +						filename = picker.getNextFile();
  17.393 +
  17.394 +						if (!filename.empty())
  17.395 +						{
  17.396 +							responses.push_back(filename);
  17.397 +						}
  17.398 +					}
  17.399 +				}
  17.400 +			}
  17.401 +			plugin->sendPickFileResponse(responses);
  17.402  		}
  17.403  		break;
  17.404  
  17.405 -
  17.406  		case LLViewerMediaObserver::MEDIA_EVENT_AUTH_REQUEST:
  17.407  		{
  17.408  			LLNotification::Params auth_request_params;
  17.409 @@ -3629,13 +3432,6 @@
  17.410  
  17.411  ////////////////////////////////////////////////////////////////////////////////
  17.412  // virtual
  17.413 -void LLViewerMediaImpl::handleCookieSet(LLPluginClassMedia* self, const std::string &cookie)
  17.414 -{
  17.415 -	LLViewerMedia::getCookieStore()->setCookies(cookie);
  17.416 -}
  17.417 -
  17.418 -////////////////////////////////////////////////////////////////////////////////
  17.419 -// virtual
  17.420  void
  17.421  LLViewerMediaImpl::cut()
  17.422  {
    18.1 --- a/indra/newview/llviewermedia.h	Wed Feb 14 11:37:07 2018 +0200
    18.2 +++ b/indra/newview/llviewermedia.h	Wed Feb 14 21:56:53 2018 +0100
    18.3 @@ -50,7 +50,6 @@
    18.4  class LLMediaEntry;
    18.5  class LLVOVolume;
    18.6  class LLMimeDiscoveryResponder;
    18.7 -class LLPluginCookieStore;
    18.8  
    18.9  typedef LLPointer<LLViewerMediaImpl> viewer_media_t;
   18.10  ///////////////////////////////////////////////////////////////////////////////
   18.11 @@ -149,13 +148,6 @@
   18.12  	// Set the proxy config for all loaded plugins
   18.13  	static void setProxyConfig(bool enable, const std::string &host, int port);
   18.14  	
   18.15 -	static LLPluginCookieStore *getCookieStore();
   18.16 -	static void loadCookieFile();
   18.17 -	static void saveCookieFile();
   18.18 -	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 );
   18.19 -	static void addSessionCookie(const std::string &name, const std::string &value, const std::string &domain, const std::string &path = std::string("/"), bool secure = false );
   18.20 -	static void removeCookie(const std::string &name, const std::string &domain, const std::string &path = std::string("/") );
   18.21 -
   18.22  	static void openIDSetup(const std::string &openid_url, const std::string &openid_token);
   18.23  	static void openIDCookieResponse(const std::string& url, const std::string &cookie);
   18.24  	
   18.25 @@ -178,7 +170,6 @@
   18.26      static void openIDSetupCoro(std::string openidUrl, std::string openidToken);
   18.27      static void getOpenIDCookieCoro(std::string url);
   18.28  
   18.29 -	static LLPluginCookieStore *sCookieStore;
   18.30  	static LLURL sOpenIDURL;
   18.31  	static std::string sOpenIDCookie;
   18.32  	static LLPluginClassMedia* sSpareBrowserMediaSource;
   18.33 @@ -337,7 +328,6 @@
   18.34  
   18.35  	// Inherited from LLPluginClassMediaOwner
   18.36  	/*virtual*/ void handleMediaEvent(LLPluginClassMedia* plugin, LLPluginClassMediaOwner::EMediaEvent);
   18.37 -	/*virtual*/ void handleCookieSet(LLPluginClassMedia* self, const std::string &cookie);
   18.38  
   18.39  	// LLEditMenuHandler overrides
   18.40  	/*virtual*/ void	cut();
    19.1 --- a/indra/newview/llwebprofile.cpp	Wed Feb 14 11:37:07 2018 +0200
    19.2 +++ b/indra/newview/llwebprofile.cpp	Wed Feb 14 21:56:53 2018 +0100
    19.3 @@ -31,7 +31,6 @@
    19.4  // libs
    19.5  #include "llbufferstream.h"
    19.6  #include "llimagepng.h"
    19.7 -#include "llplugincookiestore.h"
    19.8  
    19.9  #include "llsdserialize.h"
   19.10  
    20.1 --- a/indra/newview/skins/default/xui/en/floater_about.xml	Wed Feb 14 11:37:07 2018 +0200
    20.2 +++ b/indra/newview/skins/default/xui/en/floater_about.xml	Wed Feb 14 21:56:53 2018 +0100
    20.3 @@ -8,14 +8,14 @@
    20.4   help_topic="floater_about"
    20.5   save_rect="true"
    20.6   title="About [APP_NAME]"
    20.7 - width="470">
    20.8 + width="500">
    20.9    
   20.10    <tab_container
   20.11      follows="all" 
   20.12      top="20"
   20.13      left="7"
   20.14      height="572" 
   20.15 -    width="456" 
   20.16 +    width="486" 
   20.17      name="about_tab"
   20.18      tab_position="top">
   20.19      <panel
   20.20 @@ -46,7 +46,7 @@
   20.21          max_length="65536"
   20.22          name="support_editor"
   20.23          top_pad="5"
   20.24 -        width="444"
   20.25 +        width="474"
   20.26          word_wrap="true" />
   20.27        <button
   20.28          follows="left|top" 
   20.29 @@ -69,7 +69,7 @@
   20.30          left="4"
   20.31          name="linden_intro"
   20.32          top="16"
   20.33 -        width="444"
   20.34 +        width="474"
   20.35          wrap="true">
   20.36  Firestorm would not be possible without the decision from Linden Lab to make their Second Life viewer source code available.
   20.37  
   20.38 @@ -85,7 +85,7 @@
   20.39         max_length="65536"
   20.40         name="contrib_names"
   20.41         top_pad="5"
   20.42 -       width="446"
   20.43 +       width="476"
   20.44         word_wrap="true">
   20.45  Dummy Name replaced at run time
   20.46        </text_editor>
   20.47 @@ -122,7 +122,7 @@
   20.48                   left="5"
   20.49                   name="firestorm_intro"
   20.50                   top="0"
   20.51 -                 width="420"
   20.52 +                 width="450"
   20.53                   wrap="true">
   20.54  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.
   20.55  
   20.56 @@ -138,7 +138,7 @@
   20.57                   max_length="65536"
   20.58                   name="firestorm_names"
   20.59                   top_pad="4"
   20.60 -                 width="420"
   20.61 +                 width="450"
   20.62                   wrap="true">
   20.63  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.
   20.64                  </text>
   20.65 @@ -149,7 +149,7 @@
   20.66                   left="5"
   20.67                   name="fs_contrib_intro"
   20.68                   top_pad="8"
   20.69 -                 width="420"
   20.70 +                 width="450"
   20.71                   wrap="true">
   20.72  Additional code generously contributed to Firestorm by:
   20.73                  </text>
   20.74 @@ -163,7 +163,7 @@
   20.75                   max_length="65536"
   20.76                   name="fs_contrib_names"
   20.77                   top_pad="4"
   20.78 -                 width="420"
   20.79 +                 width="450"
   20.80                   wrap="true">
   20.81  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.
   20.82                  </text>
   20.83 @@ -174,7 +174,7 @@
   20.84                   left="5"
   20.85                   name="fs_support_intro"
   20.86                   top_pad="8"
   20.87 -                 width="420"
   20.88 +                 width="450"
   20.89                   wrap="true">
   20.90  Special thanks to our Firestorm Support Team, wiki editors, educators, and translators:
   20.91                  </text>
   20.92 @@ -188,7 +188,7 @@
   20.93                   max_length="65536"
   20.94                   name="fs_trans_names"
   20.95                   top_pad="4"
   20.96 -                 width="420"
   20.97 +                 width="450"
   20.98                   word_wrap="true">
   20.99  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.
  20.100                  </text>
  20.101 @@ -199,7 +199,7 @@
  20.102                   left="5"
  20.103                   name="fs_art_intro"
  20.104                   top_pad="8"
  20.105 -                 width="420"
  20.106 +                 width="450"
  20.107                   wrap="true">
  20.108  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;.
  20.109  
  20.110 @@ -215,7 +215,7 @@
  20.111                   max_length="65536"
  20.112                   name="fs_artists_names"
  20.113                   top_pad="4"
  20.114 -                 width="420"
  20.115 +                 width="450"
  20.116                   wrap="true">
  20.117  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.
  20.118                  </text>
  20.119 @@ -237,7 +237,7 @@
  20.120         max_length="65536"
  20.121         name="licenses_editor"
  20.122         top="16"
  20.123 -       width="444"
  20.124 +       width="474"
  20.125         word_wrap="true">
  20.126  3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion
  20.127  APR Copyright (C) 2011 The Apache Software Foundation
    21.1 --- a/indra/newview/skins/default/xui/en/floater_web_content.xml	Wed Feb 14 11:37:07 2018 +0200
    21.2 +++ b/indra/newview/skins/default/xui/en/floater_web_content.xml	Wed Feb 14 21:56:53 2018 +0100
    21.3 @@ -180,108 +180,7 @@
    21.4          width="22">
    21.5          <button.commit_callback
    21.6            function="WebContent.TestURL"
    21.7 -          parameter="https://callum-linden.s3.amazonaws.com/ceftests.html"/>
    21.8 -      </button>
    21.9 -
   21.10 -      <button
   21.11 -        image_overlay="Video_URL_Off"
   21.12 -            image_disabled="PushButton_Disabled"
   21.13 -            image_disabled_selected="PushButton_Disabled"
   21.14 -            image_selected="PushButton_Selected"
   21.15 -            image_unselected="PushButton_Off"
   21.16 -        chrome="true"
   21.17 -        tool_tip="MPEG4 Video Test"
   21.18 -        enabled="true"
   21.19 -        follows="left|top"
   21.20 -        height="22"
   21.21 -        layout="topleft"
   21.22 -        left="27"
   21.23 -        name="VLC Plugin Test MPEG4"
   21.24 -        top="0"
   21.25 -        width="22">
   21.26 -        <button.commit_callback
   21.27 -          function="WebContent.TestURL"
   21.28 -          parameter="https://callum-linden.s3.amazonaws.com/sample_media/ss.mp4"/>
   21.29 -      </button>
   21.30 -      <button
   21.31 -        image_overlay="Video_URL_Off"
   21.32 -            image_disabled="PushButton_Disabled"
   21.33 -            image_disabled_selected="PushButton_Disabled"
   21.34 -            image_selected="PushButton_Selected"
   21.35 -            image_unselected="PushButton_Off"
   21.36 -        chrome="true"
   21.37 -        tool_tip="MKV Video Test"
   21.38 -        enabled="true"
   21.39 -        follows="left|top"
   21.40 -        height="22"
   21.41 -        layout="topleft"
   21.42 -        left="51"
   21.43 -        name="VLC Plugin Test MKV"
   21.44 -        top="0"
   21.45 -        width="22">
   21.46 -        <button.commit_callback
   21.47 -          function="WebContent.TestURL"
   21.48 -          parameter="https://callum-linden.s3.amazonaws.com/sample_media/jellyfish.mkv"/>
   21.49 -      </button>
   21.50 -      <button
   21.51 -        image_overlay="Video_URL_Off"
   21.52 -            image_disabled="PushButton_Disabled"
   21.53 -            image_disabled_selected="PushButton_Disabled"
   21.54 -            image_selected="PushButton_Selected"
   21.55 -            image_unselected="PushButton_Off"
   21.56 -        chrome="true"
   21.57 -        tool_tip="WebM Video Test"
   21.58 -        enabled="true"
   21.59 -        follows="left|top"
   21.60 -        height="22"
   21.61 -        layout="topleft"
   21.62 -        left="75"
   21.63 -        name="VLC Plugin Test WebM"
   21.64 -        top="0"
   21.65 -        width="22">
   21.66 -        <button.commit_callback
   21.67 -          function="WebContent.TestURL"
   21.68 -          parameter="https://callum-linden.s3.amazonaws.com/sample_media/jumprope.webm"/>
   21.69 -      </button>
   21.70 -      <button
   21.71 -        image_overlay="Video_URL_Off"
   21.72 -            image_disabled="PushButton_Disabled"
   21.73 -            image_disabled_selected="PushButton_Disabled"
   21.74 -            image_selected="PushButton_Selected"
   21.75 -            image_unselected="PushButton_Off"
   21.76 -        chrome="true"
   21.77 -        tool_tip="MP3 audio Test"
   21.78 -        enabled="true"
   21.79 -        follows="left|top"
   21.80 -        height="22"
   21.81 -        layout="topleft"
   21.82 -        left="99"
   21.83 -        name="VLC Plugin Test MP3"
   21.84 -        top="0"
   21.85 -        width="22">
   21.86 -        <button.commit_callback
   21.87 -          function="WebContent.TestURL"
   21.88 -          parameter="https://callum-linden.s3.amazonaws.com/alegria.mp3"/>
   21.89 -      </button>
   21.90 -      <button
   21.91 -        image_overlay="Video_URL_Off"
   21.92 -            image_disabled="PushButton_Disabled"
   21.93 -            image_disabled_selected="PushButton_Disabled"
   21.94 -            image_selected="PushButton_Selected"
   21.95 -            image_unselected="PushButton_Off"
   21.96 -        chrome="true"
   21.97 -        tool_tip="FLV Test"
   21.98 -        enabled="true"
   21.99 -        follows="left|top"
  21.100 -        height="22"
  21.101 -        layout="topleft"
  21.102 -        left="123"
  21.103 -        name="VLC Plugin Test FLV"
  21.104 -        top="0"
  21.105 -        width="22">
  21.106 -        <button.commit_callback
  21.107 -          function="WebContent.TestURL"
  21.108 -          parameter="https://callum-linden.s3.amazonaws.com/sample_media/vandal.flv"/>
  21.109 +          parameter="https://sl-viewer-media-system.s3.amazonaws.com/index.html"/>
  21.110        </button>
  21.111      </layout_panel>
  21.112      <layout_panel
    22.1 --- a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml	Wed Feb 14 11:37:07 2018 +0200
    22.2 +++ b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml	Wed Feb 14 21:56:53 2018 +0100
    22.3 @@ -51,7 +51,7 @@
    22.4      follows="left|top"
    22.5      height="23"
    22.6      label="Clear History"
    22.7 -    tool_tip="Clear login image, last location, teleport history, web, and texture cache"
    22.8 +    tool_tip="Clear login image, last location, teleport history, web and texture cache"
    22.9      layout="topleft"
   22.10      left="15"
   22.11      name="clear_cache"
    23.1 --- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml	Wed Feb 14 11:37:07 2018 +0200
    23.2 +++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml	Wed Feb 14 21:56:53 2018 +0100
    23.3 @@ -215,7 +215,6 @@
    23.4  		 width="400">
    23.5  			Web browser:
    23.6  		</text>
    23.7 -
    23.8  	  <radio_group
    23.9  	   control_name="PreferredBrowserBehavior"
   23.10  	   follows="left|top"
   23.11 @@ -227,7 +226,7 @@
   23.12  	   width="480">
   23.13  		<radio_item
   23.14  		  height="20"
   23.15 -		  label="Use my browser (Chrome, Firefox, IE) for all links"
   23.16 +		  label="Use the default system browser for all links"
   23.17  		  layout="topleft"
   23.18  		  left="0"
   23.19  		  name="new_external"
   23.20 @@ -237,18 +236,18 @@
   23.21  		  width="480" />
   23.22  		<radio_item
   23.23  		  height="20"
   23.24 -		  label="Use built-in browser for Second Life links only"
   23.25 +		  label="Use the built-in browser for Second Life links only"
   23.26  		  layout="topleft"
   23.27  		  left_delta="0"
   23.28  		  name="new_internal"
   23.29  		  value="1"      
   23.30 -		  tool_tip="Use the default system web browser for help, web links, etc. Builtin browser will be used only for LindenLab/SecondLife links."
   23.31 +		  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."
   23.32  		  top_delta="15"
   23.33  		  width="480" />
   23.34  		<radio_item
   23.35  		  top_delta="15"
   23.36  		  height="20"
   23.37 -		  label="Use built-in browser for all links"
   23.38 +		  label="Use the built-in browser for all links"
   23.39  		  layout="topleft"
   23.40  		  left="0"
   23.41  		  name="new_internal_all"
   23.42 @@ -328,23 +327,6 @@
   23.43  		 follows="left|top"
   23.44  		 height="16"
   23.45  		 initial_value="true"
   23.46 -		 control_name="CookiesEnabled"
   23.47 -		 label="Accept cookies"
   23.48 -		 left_delta="0"
   23.49 -		 mouse_opaque="true"
   23.50 -		 name="cookies_enabled"
   23.51 -		 radio_style="false"
   23.52 -		 width="200"
   23.53 -		 top_pad="5">
   23.54 -			<check_box.commit_callback
   23.55 -			 function="Pref.Cookies" />
   23.56 -		</check_box>
   23.57 -
   23.58 -		<check_box
   23.59 -		 enabled="true"
   23.60 -		 follows="left|top"
   23.61 -		 height="16"
   23.62 -		 initial_value="true"
   23.63  		 control_name="BrowserJavascriptEnabled"
   23.64  		 label="Enable Javascript"
   23.65  		 left_delta="0"

mercurial