Merged in lindenlab/viewer-release

Thu, 12 Apr 2018 21:22:22 +0300

author
AndreyL ProductEngine <alihatskiy@productengine.com>
date
Thu, 12 Apr 2018 21:22:22 +0300
changeset 55366
48189ac2268d
parent 55363
1e9828e37a4d
parent 55096
cfe9b2a47671
child 55367
f171b6bd81a3
child 55370
212fc2d2ee0c

Merged in lindenlab/viewer-release

indra/llplugin/llpluginclassmedia.cpp 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/llstartup.cpp file | annotate | diff | revisions
indra/newview/llviewermedia.cpp file | annotate | diff | revisions
indra/newview/skins/default/xui/en/menu_viewer.xml file | annotate | diff | revisions
     1.1 --- a/.hgtags	Fri Apr 06 14:15:11 2018 +0000
     1.2 +++ b/.hgtags	Thu Apr 12 21:22:22 2018 +0300
     1.3 @@ -534,3 +534,4 @@
     1.4  ad0e15543836d64d6399d28b32852510435e344a 5.1.0-release
     1.5  26d9e9bb166a9a417f35b1863223a597af8185fd 5.1.1-release
     1.6  2eb917875efdfe920680b9049302d0f03721245d 5.1.2-release
     1.7 +7c00e5b6cb3d95712e9d8e29277c805bca2bda90 5.1.3-release
     2.1 --- a/autobuild.xml	Fri Apr 06 14:15:11 2018 +0000
     2.2 +++ b/autobuild.xml	Thu Apr 12 21:22:22 2018 +0300
     2.3 @@ -556,9 +556,9 @@
     2.4              <key>archive</key>
     2.5              <map>
     2.6                <key>hash</key>
     2.7 -              <string>bbdea742f2a89bcd6360e61e01d6be93</string>
     2.8 +              <string>118987b1a5b56214cfdbd0c763e180da</string>
     2.9                <key>url</key>
    2.10 -              <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>
    2.11 +              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/15127/97748/dullahan-1.1.1080_3.3325.1750.gaabe4c4-darwin64-513449.tar.bz2</string>
    2.12              </map>
    2.13              <key>name</key>
    2.14              <string>darwin64</string>
    2.15 @@ -568,9 +568,9 @@
    2.16              <key>archive</key>
    2.17              <map>
    2.18                <key>hash</key>
    2.19 -              <string>31e11a74e0d3f1e5e4036cb5fea8d944</string>
    2.20 +              <string>2ecc71350b30a1057091b9cd7af18b1c</string>
    2.21                <key>url</key>
    2.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>
    2.23 +              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/15128/97755/dullahan-1.1.1080_3.3325.1750.gaabe4c4-windows-513449.tar.bz2</string>
    2.24              </map>
    2.25              <key>name</key>
    2.26              <string>windows</string>
    2.27 @@ -580,16 +580,16 @@
    2.28              <key>archive</key>
    2.29              <map>
    2.30                <key>hash</key>
    2.31 -              <string>f965d244e7921c06ee79b68a4abcea3b</string>
    2.32 +              <string>2ed3e49388514dafb907c59a209d580e</string>
    2.33                <key>url</key>
    2.34 -              <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>
    2.35 +              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/15129/97760/dullahan-1.1.1080_3.3325.1750.gaabe4c4-windows64-513449.tar.bz2</string>
    2.36              </map>
    2.37              <key>name</key>
    2.38              <string>windows64</string>
    2.39            </map>
    2.40          </map>
    2.41          <key>version</key>
    2.42 -        <string>1.1.820_3.3071.1634.g9cc59c8</string>
    2.43 +        <string>1.1.1080_3.3325.1750.gaabe4c4</string>
    2.44        </map>
    2.45        <key>elfio</key>
    2.46        <map>
    2.47 @@ -3316,9 +3316,9 @@
    2.48              <key>archive</key>
    2.49              <map>
    2.50                <key>hash</key>
    2.51 -              <string>c5e6d9440e3a4a12102dd2bbb703963e</string>
    2.52 +              <string>e5635e173c75dc0675b48ab5f5e4868b</string>
    2.53                <key>url</key>
    2.54 -              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/2225/4736/vlc_bin-2.2.4.502214-darwin64-502214.tar.bz2</string>
    2.55 +              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/12143/71451/vlc_bin-2.2.8.511703-darwin64-511703.tar.bz2</string>
    2.56              </map>
    2.57              <key>name</key>
    2.58              <string>darwin64</string>
    2.59 @@ -3340,9 +3340,9 @@
    2.60              <key>archive</key>
    2.61              <map>
    2.62                <key>hash</key>
    2.63 -              <string>dc37f7cc77a62891bb9ae46c9e19f95e</string>
    2.64 +              <string>add560654a53cb1c554044a4fac3c718</string>
    2.65                <key>url</key>
    2.66 -              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1219/2834/vlc_bin-2.2.4.501207-windows-501207.tar.bz2</string>
    2.67 +              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/12144/71458/vlc_bin-2.2.8.511703-windows-511703.tar.bz2</string>
    2.68              </map>
    2.69              <key>name</key>
    2.70              <string>windows</string>
    2.71 @@ -3352,16 +3352,16 @@
    2.72              <key>archive</key>
    2.73              <map>
    2.74                <key>hash</key>
    2.75 -              <string>148ee599afeba9794de14ca433389504</string>
    2.76 +              <string>94bf04b49acc1e1bf2c06e2232f8a083</string>
    2.77                <key>url</key>
    2.78 -              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1218/2829/vlc_bin-2.2.4.501207-windows64-501207.tar.bz2</string>
    2.79 +              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/12145/71463/vlc_bin-2.2.8.511703-windows64-511703.tar.bz2</string>
    2.80              </map>
    2.81              <key>name</key>
    2.82              <string>windows64</string>
    2.83            </map>
    2.84          </map>
    2.85          <key>version</key>
    2.86 -        <string>2.2.4.502214</string>
    2.87 +        <string>2.2.8.511703</string>
    2.88        </map>
    2.89        <key>xmlrpc-epi</key>
    2.90        <map>
     3.1 --- a/indra/llplugin/CMakeLists.txt	Fri Apr 06 14:15:11 2018 +0000
     3.2 +++ b/indra/llplugin/CMakeLists.txt	Thu Apr 12 21:22:22 2018 +0300
     3.3 @@ -29,7 +29,6 @@
     3.4  
     3.5  set(llplugin_SOURCE_FILES
     3.6      llpluginclassmedia.cpp
     3.7 -    llplugincookiestore.cpp
     3.8      llplugininstance.cpp
     3.9      llpluginmessage.cpp
    3.10      llpluginmessagepipe.cpp
    3.11 @@ -43,7 +42,6 @@
    3.12  
    3.13      llpluginclassmedia.h
    3.14      llpluginclassmediaowner.h
    3.15 -    llplugincookiestore.h
    3.16      llplugininstance.h
    3.17      llpluginmessage.h
    3.18      llpluginmessageclasses.h
    3.19 @@ -70,20 +68,3 @@
    3.20  
    3.21  add_subdirectory(slplugin)
    3.22  
    3.23 -# Add tests
    3.24 -if (LL_TESTS)
    3.25 -    include(LLAddBuildTest)
    3.26 -    # UNIT TESTS
    3.27 -    SET(llplugin_TEST_SOURCE_FILES
    3.28 -      llplugincookiestore.cpp
    3.29 -      )
    3.30 -
    3.31 -    # llplugincookiestore has a dependency on curl, so we need to link the curl library into the test.
    3.32 -    set_source_files_properties(
    3.33 -      llplugincookiestore.cpp
    3.34 -      PROPERTIES
    3.35 -        LL_TEST_ADDITIONAL_LIBRARIES "${CURL_LIBRARIES};${NGHTTP2_LIBRARIES}"
    3.36 -      )
    3.37 -
    3.38 -    LL_ADD_PROJECT_UNIT_TESTS(llplugin "${llplugin_TEST_SOURCE_FILES}")
    3.39 -endif (LL_TESTS)
     4.1 --- a/indra/llplugin/llpluginclassmedia.cpp	Fri Apr 06 14:15:11 2018 +0000
     4.2 +++ b/indra/llplugin/llpluginclassmedia.cpp	Thu Apr 12 21:22:22 2018 +0300
     4.3 @@ -31,6 +31,9 @@
     4.4  
     4.5  #include "llpluginclassmedia.h"
     4.6  #include "llpluginmessageclasses.h"
     4.7 +#include "llcontrol.h"
     4.8 +
     4.9 +extern LLControlGroup gSavedSettings;    
    4.10  
    4.11  static int LOW_PRIORITY_TEXTURE_SIZE_DEFAULT = 256;
    4.12  
    4.13 @@ -792,15 +795,22 @@
    4.14  	return result;
    4.15  }
    4.16  
    4.17 -void LLPluginClassMedia::sendPickFileResponse(const std::string &file)
    4.18 +void LLPluginClassMedia::sendPickFileResponse(const std::vector<std::string> files)
    4.19  {
    4.20  	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file_response");
    4.21 -	message.setValue("file", file);
    4.22  	if(mPlugin && mPlugin->isBlocked())
    4.23  	{
    4.24  		// If the plugin sent a blocking pick-file request, the response should unblock it.
    4.25  		message.setValueBoolean("blocking_response", true);
    4.26  	}
    4.27 +
    4.28 +	LLSD file_list = LLSD::emptyArray();
    4.29 +	for (std::vector<std::string>::const_iterator in_iter = files.begin(); in_iter != files.end(); ++in_iter)
    4.30 +	{
    4.31 +		file_list.append(LLSD::String(*in_iter));
    4.32 +	}
    4.33 +	message.setValueLLSD("file_list", file_list);
    4.34 +
    4.35  	sendMessage(message);
    4.36  }
    4.37  
    4.38 @@ -836,11 +846,17 @@
    4.39  	sendMessage(message);
    4.40  }
    4.41  
    4.42 -void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path_cache, const std::string &user_data_path_cookies)
    4.43 +void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path_cache,
    4.44 +										 const std::string &user_data_path_cookies,
    4.45 +										 const std::string &user_data_path_cef_log)
    4.46  {
    4.47  	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "set_user_data_path");
    4.48  	message.setValue("cache_path", user_data_path_cache);
    4.49  	message.setValue("cookies_path", user_data_path_cookies);
    4.50 +	message.setValue("cef_log_file", user_data_path_cef_log);
    4.51 +
    4.52 +	bool cef_verbose_log = gSavedSettings.getBOOL("CefVerboseLog");
    4.53 +	message.setValueBoolean("cef_verbose_log", cef_verbose_log);
    4.54  	sendMessage(message);
    4.55  }
    4.56  
    4.57 @@ -1092,6 +1108,7 @@
    4.58  		}
    4.59  		else if(message_name == "pick_file")
    4.60  		{
    4.61 +			mIsMultipleFilePick = message.getValueBoolean("multiple_files");
    4.62  			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PICK_FILE_REQUEST);
    4.63  		}
    4.64  		else if(message_name == "auth_request")
    4.65 @@ -1153,7 +1170,12 @@
    4.66  		{
    4.67  			mClickURL = message.getValue("uri");
    4.68  			mClickTarget = message.getValue("target");
    4.69 -			mClickUUID = message.getValue("uuid");
    4.70 +
    4.71 +			// need a link to have a UUID that identifies it to a system further
    4.72 +			// upstream - plugin could make it but we have access to LLUUID here
    4.73 +			// so why don't we use it
    4.74 +			mClickUUID = LLUUID::generateNewID().asString();
    4.75 +
    4.76  			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_HREF);
    4.77  		}
    4.78  		else if(message_name == "click_nofollow")
    4.79 @@ -1168,13 +1190,6 @@
    4.80  			mStatusCode = message.getValueS32("status_code");
    4.81  			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAVIGATE_ERROR_PAGE);
    4.82  		}
    4.83 -		else if(message_name == "cookie_set")
    4.84 -		{
    4.85 -			if(mOwner)
    4.86 -			{
    4.87 -				mOwner->handleCookieSet(this, message.getValue("cookie"));
    4.88 -			}
    4.89 -		}
    4.90  		else if(message_name == "close_request")
    4.91  		{
    4.92  			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLOSE_REQUEST);
    4.93 @@ -1289,16 +1304,9 @@
    4.94  	sendMessage(message);
    4.95  }
    4.96  
    4.97 -void LLPluginClassMedia::set_cookies(const std::string &cookies)
    4.98 +void LLPluginClassMedia::cookies_enabled(bool enable)
    4.99  {
   4.100 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_cookies");
   4.101 -	message.setValue("cookies", cookies);
   4.102 -	sendMessage(message);
   4.103 -}
   4.104 -
   4.105 -void LLPluginClassMedia::enable_cookies(bool enable)
   4.106 -{
   4.107 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "enable_cookies");
   4.108 +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "cookies_enabled");
   4.109  	message.setValueBoolean("enable", enable);
   4.110  	sendMessage(message);
   4.111  }
     5.1 --- a/indra/llplugin/llpluginclassmedia.h	Fri Apr 06 14:15:11 2018 +0000
     5.2 +++ b/indra/llplugin/llpluginclassmedia.h	Thu Apr 12 21:22:22 2018 +0300
     5.3 @@ -176,7 +176,7 @@
     5.4  	
     5.5  	F64 getCPUUsage();
     5.6  	
     5.7 -	void sendPickFileResponse(const std::string &file);
     5.8 +	void sendPickFileResponse(const std::vector<std::string> files);
     5.9  
    5.10  	void sendAuthResponse(bool ok, const std::string &username, const std::string &password);
    5.11  
    5.12 @@ -195,7 +195,7 @@
    5.13  	bool	canPaste() const { return mCanPaste; };
    5.14  	
    5.15  	// These can be called before init(), and they will be queued and sent before the media init message.
    5.16 -	void	setUserDataPath(const std::string &user_data_path_cache, const std::string &user_data_path_cookies);
    5.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);
    5.18  	void	setLanguageCode(const std::string &language_code);
    5.19  	void	setPluginsEnabled(const bool enabled);
    5.20  	void	setJavascriptEnabled(const bool enabled);
    5.21 @@ -210,7 +210,7 @@
    5.22  	void clear_cache();
    5.23  	void clear_cookies();
    5.24  	void set_cookies(const std::string &cookies);
    5.25 -	void enable_cookies(bool enable);
    5.26 +	void cookies_enabled(bool enable);
    5.27  	void proxy_setup(bool enable, const std::string &host = LLStringUtil::null, int port = 0);
    5.28  	void browse_stop();
    5.29  	void browse_reload(bool ignore_cache = false);
    5.30 @@ -277,6 +277,9 @@
    5.31  	std::string	getAuthURL() const { return mAuthURL; };
    5.32  	std::string	getAuthRealm() const { return mAuthRealm; };
    5.33  
    5.34 +	// These are valid during MEDIA_EVENT_PICK_FILE_REQUEST
    5.35 +	bool getIsMultipleFilePick() const { return mIsMultipleFilePick; }
    5.36 +
    5.37  	// These are valid during MEDIA_EVENT_LINK_HOVERED
    5.38  	std::string	getHoverText() const { return mHoverText; };
    5.39  	std::string	getHoverLink() const { return mHoverLink; };
    5.40 @@ -435,6 +438,7 @@
    5.41  	std::string		mHoverText;
    5.42  	std::string		mHoverLink;
    5.43  	std::string     mFileDownloadFilename;
    5.44 +	bool			mIsMultipleFilePick;
    5.45  	
    5.46  	/////////////////////////////////////////
    5.47  	// media_time class
     6.1 --- a/indra/llplugin/llpluginclassmediaowner.h	Fri Apr 06 14:15:11 2018 +0000
     6.2 +++ b/indra/llplugin/llpluginclassmediaowner.h	Thu Apr 12 21:22:22 2018 +0300
     6.3 @@ -1,4 +1,4 @@
     6.4 -/** 
     6.5 +/**
     6.6   * @file llpluginclassmediaowner.h
     6.7   * @brief LLPluginClassMedia handles interaction with a plugin which knows about the "media" message class.
     6.8   *
     6.9 @@ -6,21 +6,21 @@
    6.10   * $LicenseInfo:firstyear=2008&license=viewerlgpl$
    6.11   * Second Life Viewer Source Code
    6.12   * Copyright (C) 2010, Linden Research, Inc.
    6.13 - * 
    6.14 + *
    6.15   * This library is free software; you can redistribute it and/or
    6.16   * modify it under the terms of the GNU Lesser General Public
    6.17   * License as published by the Free Software Foundation;
    6.18   * version 2.1 of the License only.
    6.19 - * 
    6.20 + *
    6.21   * This library is distributed in the hope that it will be useful,
    6.22   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.23   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    6.24   * Lesser General Public License for more details.
    6.25 - * 
    6.26 + *
    6.27   * You should have received a copy of the GNU Lesser General Public
    6.28   * License along with this library; if not, write to the Free Software
    6.29   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
    6.30 - * 
    6.31 + *
    6.32   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
    6.33   * $/LicenseInfo$
    6.34   * @endcond
    6.35 @@ -34,18 +34,17 @@
    6.36  #include <queue>
    6.37  
    6.38  class LLPluginClassMedia;
    6.39 -class LLPluginCookieStore;
    6.40  
    6.41  class LLPluginClassMediaOwner
    6.42  {
    6.43  public:
    6.44  	typedef enum
    6.45  	{
    6.46 -		MEDIA_EVENT_CONTENT_UPDATED,		// contents/dirty rect have updated 
    6.47 +		MEDIA_EVENT_CONTENT_UPDATED,		// contents/dirty rect have updated
    6.48  		MEDIA_EVENT_TIME_DURATION_UPDATED,	// current time and/or duration have updated
    6.49  		MEDIA_EVENT_SIZE_CHANGED,			// media size has changed
    6.50  		MEDIA_EVENT_CURSOR_CHANGED,			// plugin has requested a cursor change
    6.51 -		
    6.52 +
    6.53  		MEDIA_EVENT_NAVIGATE_BEGIN,			// browser has begun navigation
    6.54  		MEDIA_EVENT_NAVIGATE_COMPLETE,		// browser has finished navigation
    6.55  		MEDIA_EVENT_PROGRESS_UPDATED,		// browser has updated loading progress
    6.56 @@ -58,8 +57,8 @@
    6.57  		MEDIA_EVENT_CLOSE_REQUEST,			// The plugin requested its window be closed (currently hooked up to javascript window.close in webkit)
    6.58  		MEDIA_EVENT_PICK_FILE_REQUEST,		// The plugin wants the user to pick a file
    6.59  		MEDIA_EVENT_GEOMETRY_CHANGE,		// The plugin requested its window geometry be changed (per the javascript window interface)
    6.60 -	
    6.61 -		MEDIA_EVENT_PLUGIN_FAILED_LAUNCH,	// The plugin failed to launch 
    6.62 +
    6.63 +		MEDIA_EVENT_PLUGIN_FAILED_LAUNCH,	// The plugin failed to launch
    6.64  		MEDIA_EVENT_PLUGIN_FAILED,			// The plugin died unexpectedly
    6.65  
    6.66  		MEDIA_EVENT_AUTH_REQUEST,			// The plugin wants to display an auth dialog
    6.67 @@ -69,9 +68,9 @@
    6.68  		MEDIA_EVENT_DEBUG_MESSAGE,			// plugin sending back debug information for host to process
    6.69  
    6.70  		MEDIA_EVENT_LINK_HOVERED			// Got a "link hovered" event from the plugin
    6.71 -		
    6.72 +
    6.73  	} EMediaEvent;
    6.74 -	
    6.75 +
    6.76  	typedef enum
    6.77  	{
    6.78  		MEDIA_NONE,			// Uninitialized -- no useful state
    6.79 @@ -81,12 +80,11 @@
    6.80  		MEDIA_PLAYING,		// playing (only for time-based media)
    6.81  		MEDIA_PAUSED,		// paused (only for time-based media)
    6.82  		MEDIA_DONE			// finished playing (only for time-based media)
    6.83 -	
    6.84 +
    6.85  	} EMediaStatus;
    6.86 -	
    6.87 +
    6.88  	virtual ~LLPluginClassMediaOwner() {};
    6.89  	virtual void handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent /*event*/) {};
    6.90 -	virtual void handleCookieSet(LLPluginClassMedia* /*self*/, const std::string &/*cookie*/) {};
    6.91  };
    6.92  
    6.93  #endif // LL_LLPLUGINCLASSMEDIAOWNER_H
     7.1 --- a/indra/llplugin/llplugincookiestore.cpp	Fri Apr 06 14:15:11 2018 +0000
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,689 +0,0 @@
     7.4 -/** 
     7.5 - * @file llplugincookiestore.cpp
     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 -#include "linden_common.h"
    7.33 -#include "llstl.h"
    7.34 -#include "indra_constants.h"
    7.35 -
    7.36 -#include "llplugincookiestore.h"
    7.37 -#include <iostream>
    7.38 -
    7.39 -// for curl_getdate() (apparently parsing RFC 1123 dates is hard)
    7.40 -#include <curl/curl.h>
    7.41 -
    7.42 -LLPluginCookieStore::LLPluginCookieStore():
    7.43 -	mHasChangedCookies(false)
    7.44 -{
    7.45 -}
    7.46 -
    7.47 -
    7.48 -LLPluginCookieStore::~LLPluginCookieStore()
    7.49 -{
    7.50 -	clearCookies();
    7.51 -}
    7.52 -
    7.53 -
    7.54 -LLPluginCookieStore::Cookie::Cookie(const std::string &s, std::string::size_type cookie_start, std::string::size_type cookie_end):
    7.55 -	mCookie(s, cookie_start, cookie_end - cookie_start),
    7.56 -	mNameStart(0), mNameEnd(0),
    7.57 -	mValueStart(0), mValueEnd(0),
    7.58 -	mDomainStart(0), mDomainEnd(0),
    7.59 -	mPathStart(0), mPathEnd(0),
    7.60 -	mDead(false), mChanged(true)
    7.61 -{
    7.62 -}
    7.63 -
    7.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)
    7.65 -{
    7.66 -	Cookie *result = new Cookie(s, cookie_start, cookie_end);
    7.67 -
    7.68 -	if(!result->parse(host))
    7.69 -	{
    7.70 -		delete result;
    7.71 -		result = NULL;
    7.72 -	}
    7.73 -	
    7.74 -	return result;
    7.75 -}
    7.76 -
    7.77 -std::string LLPluginCookieStore::Cookie::getKey() const
    7.78 -{
    7.79 -	std::string result;
    7.80 -	if(mDomainEnd > mDomainStart)
    7.81 -	{
    7.82 -		result += mCookie.substr(mDomainStart, mDomainEnd - mDomainStart);
    7.83 -	}
    7.84 -	result += ';';
    7.85 -	if(mPathEnd > mPathStart)
    7.86 -	{
    7.87 -		result += mCookie.substr(mPathStart, mPathEnd - mPathStart);
    7.88 -	}
    7.89 -	result += ';';
    7.90 -	result += mCookie.substr(mNameStart, mNameEnd - mNameStart);
    7.91 -	return result;
    7.92 -}
    7.93 -
    7.94 -std::string LLPluginCookieStore::Cookie::getDomain() const
    7.95 -{
    7.96 -	std::string result;
    7.97 -	if(mDomainEnd > mDomainStart)
    7.98 -	{
    7.99 -		result += mCookie.substr(mDomainStart, mDomainEnd - mDomainStart);
   7.100 -	}
   7.101 -	return result;
   7.102 -}
   7.103 -
   7.104 -bool LLPluginCookieStore::Cookie::parse(const std::string &host)
   7.105 -{
   7.106 -	bool first_field = true;
   7.107 -
   7.108 -	std::string::size_type cookie_end = mCookie.size();
   7.109 -	std::string::size_type field_start = 0;
   7.110 -
   7.111 -	LL_DEBUGS("CookieStoreParse") << "parsing cookie: " << mCookie << LL_ENDL;
   7.112 -	while(field_start < cookie_end)
   7.113 -	{
   7.114 -		// Finding the start of the next field requires honoring special quoting rules
   7.115 -		// see the definition of 'quoted-string' in rfc2616 for details
   7.116 -		std::string::size_type next_field_start = findFieldEnd(field_start);
   7.117 -
   7.118 -		// The end of this field should not include the terminating ';' or any trailing whitespace
   7.119 -		std::string::size_type field_end = mCookie.find_last_not_of("; ", next_field_start);
   7.120 -		if(field_end == std::string::npos || field_end < field_start)
   7.121 -		{
   7.122 -			// This field was empty or all whitespace.  Set end = start so it shows as empty.
   7.123 -			field_end = field_start;
   7.124 -		}
   7.125 -		else if (field_end < next_field_start)
   7.126 -		{
   7.127 -			// we actually want the index of the char _after_ what 'last not of' found
   7.128 -			++field_end;
   7.129 -		}
   7.130 -		
   7.131 -		// find the start of the actual name (skip separator and possible whitespace)
   7.132 -		std::string::size_type name_start = mCookie.find_first_not_of("; ", field_start);
   7.133 -		if(name_start == std::string::npos || name_start > next_field_start)
   7.134 -		{
   7.135 -			// Again, nothing but whitespace.
   7.136 -			name_start = field_start;
   7.137 -		}
   7.138 -		
   7.139 -		// the name and value are separated by the first equals sign
   7.140 -		std::string::size_type name_value_sep = mCookie.find_first_of("=", name_start);
   7.141 -		if(name_value_sep == std::string::npos || name_value_sep > field_end)
   7.142 -		{
   7.143 -			// No separator found, so this is a field without an = 
   7.144 -			name_value_sep = field_end;
   7.145 -		}
   7.146 -		
   7.147 -		// the name end is before the name-value separator
   7.148 -		std::string::size_type name_end = mCookie.find_last_not_of("= ", name_value_sep);
   7.149 -		if(name_end == std::string::npos || name_end < name_start)
   7.150 -		{
   7.151 -			// I'm not sure how we'd hit this case... it seems like it would have to be an empty name.
   7.152 -			name_end = name_start;
   7.153 -		}
   7.154 -		else if (name_end < name_value_sep)
   7.155 -		{
   7.156 -			// we actually want the index of the char _after_ what 'last not of' found
   7.157 -			++name_end;
   7.158 -		}
   7.159 -		
   7.160 -		// Value is between the name-value sep and the end of the field.
   7.161 -		std::string::size_type value_start = mCookie.find_first_not_of("= ", name_value_sep);
   7.162 -		if(value_start == std::string::npos || value_start > field_end)
   7.163 -		{
   7.164 -			// All whitespace or empty value
   7.165 -			value_start = field_end;
   7.166 -		}
   7.167 -		std::string::size_type value_end = mCookie.find_last_not_of("; ", field_end);
   7.168 -		if(value_end == std::string::npos || value_end < value_start)
   7.169 -		{
   7.170 -			// All whitespace or empty value
   7.171 -			value_end = value_start;
   7.172 -		}
   7.173 -		else if (value_end < field_end)
   7.174 -		{
   7.175 -			// we actually want the index of the char _after_ what 'last not of' found
   7.176 -			++value_end;
   7.177 -		}
   7.178 -
   7.179 -		LL_DEBUGS("CookieStoreParse") 
   7.180 -			<< "    field name: \"" << mCookie.substr(name_start, name_end - name_start) 
   7.181 -			<< "\", value: \"" << mCookie.substr(value_start, value_end - value_start) << "\""
   7.182 -			<< LL_ENDL;
   7.183 -				
   7.184 -		// See whether this field is one we know
   7.185 -		if(first_field)
   7.186 -		{
   7.187 -			// The first field is the name=value pair
   7.188 -			mNameStart = name_start;
   7.189 -			mNameEnd = name_end;
   7.190 -			mValueStart = value_start;
   7.191 -			mValueEnd = value_end;
   7.192 -			first_field = false;
   7.193 -		}
   7.194 -		else
   7.195 -		{
   7.196 -			// Subsequent fields must come from the set in rfc2109
   7.197 -			if(matchName(name_start, name_end, "expires"))
   7.198 -			{
   7.199 -				std::string date_string(mCookie, value_start, value_end - value_start); 
   7.200 -				// If the cookie contains an "expires" field, it MUST contain a parsable date.
   7.201 -				
   7.202 -				// HACK: LLDate apparently can't PARSE an rfc1123-format date, even though it can GENERATE one.
   7.203 -				//  The curl function curl_getdate can do this, but I'm hesitant to unilaterally introduce a curl dependency in LLDate.
   7.204 -#if 1
   7.205 -				time_t date = curl_getdate(date_string.c_str(), NULL );
   7.206 -				mDate.secondsSinceEpoch((F64)date);
   7.207 -				LL_DEBUGS("CookieStoreParse") << "        expire date parsed to: " << mDate.asRFC1123() << LL_ENDL;
   7.208 -#else
   7.209 -				// This doesn't work (rfc1123-format dates cause it to fail)
   7.210 -				if(!mDate.fromString(date_string))
   7.211 -				{
   7.212 -					// Date failed to parse.
   7.213 -					LL_WARNS("CookieStoreParse") << "failed to parse cookie's expire date: " << date << LL_ENDL;
   7.214 -					return false;
   7.215 -				}
   7.216 -#endif
   7.217 -			}
   7.218 -			else if(matchName(name_start, name_end, "domain"))
   7.219 -			{
   7.220 -				mDomainStart = value_start;
   7.221 -				mDomainEnd = value_end;
   7.222 -			}
   7.223 -			else if(matchName(name_start, name_end, "path"))
   7.224 -			{
   7.225 -				mPathStart = value_start;
   7.226 -				mPathEnd = value_end;
   7.227 -			}
   7.228 -			else if(matchName(name_start, name_end, "max-age"))
   7.229 -			{
   7.230 -				// TODO: how should we handle this?
   7.231 -			}
   7.232 -			else if(matchName(name_start, name_end, "secure"))
   7.233 -			{
   7.234 -				// We don't care about the value of this field (yet)
   7.235 -			}
   7.236 -			else if(matchName(name_start, name_end, "version"))
   7.237 -			{
   7.238 -				// We don't care about the value of this field (yet)
   7.239 -			}
   7.240 -			else if(matchName(name_start, name_end, "comment"))
   7.241 -			{
   7.242 -				// We don't care about the value of this field (yet)
   7.243 -			}
   7.244 -			else if(matchName(name_start, name_end, "httponly"))
   7.245 -			{
   7.246 -				// We don't care about the value of this field (yet)
   7.247 -			}
   7.248 -			else
   7.249 -			{
   7.250 -				// An unknown field is a parse failure
   7.251 -				LL_WARNS("CookieStoreParse") << "unexpected field name: " << mCookie.substr(name_start, name_end - name_start) << LL_ENDL;
   7.252 -				return false;
   7.253 -			}
   7.254 -			
   7.255 -		}
   7.256 -
   7.257 -		
   7.258 -		// move on to the next field, skipping this field's separator and any leading whitespace
   7.259 -		field_start = mCookie.find_first_not_of("; ", next_field_start);
   7.260 -	}
   7.261 -		
   7.262 -	// The cookie MUST have a name
   7.263 -	if(mNameEnd <= mNameStart)
   7.264 -		return false;
   7.265 -	
   7.266 -	// If the cookie doesn't have a domain, add the current host as the domain.
   7.267 -	if(mDomainEnd <= mDomainStart)
   7.268 -	{
   7.269 -		if(host.empty())
   7.270 -		{
   7.271 -			// no domain and no current host -- this is a parse failure.
   7.272 -			return false;
   7.273 -		}
   7.274 -		
   7.275 -		// Figure out whether this cookie ended with a ";" or not...
   7.276 -		std::string::size_type last_char = mCookie.find_last_not_of(" ");
   7.277 -		if((last_char != std::string::npos) && (mCookie[last_char] != ';'))
   7.278 -		{
   7.279 -			mCookie += ";";
   7.280 -		}
   7.281 -		
   7.282 -		mCookie += " domain=";
   7.283 -		mDomainStart = mCookie.size();
   7.284 -		mCookie += host;
   7.285 -		mDomainEnd = mCookie.size();
   7.286 -		
   7.287 -		LL_DEBUGS("CookieStoreParse") << "added domain (" << mDomainStart << " to " << mDomainEnd << "), new cookie is: " << mCookie << LL_ENDL;
   7.288 -	}
   7.289 -
   7.290 -	// If the cookie doesn't have a path, add "/".
   7.291 -	if(mPathEnd <= mPathStart)
   7.292 -	{
   7.293 -		// Figure out whether this cookie ended with a ";" or not...
   7.294 -		std::string::size_type last_char = mCookie.find_last_not_of(" ");
   7.295 -		if((last_char != std::string::npos) && (mCookie[last_char] != ';'))
   7.296 -		{
   7.297 -			mCookie += ";";
   7.298 -		}
   7.299 -		
   7.300 -		mCookie += " path=";
   7.301 -		mPathStart = mCookie.size();
   7.302 -		mCookie += "/";
   7.303 -		mPathEnd = mCookie.size();
   7.304 -		
   7.305 -		LL_DEBUGS("CookieStoreParse") << "added path (" << mPathStart << " to " << mPathEnd << "), new cookie is: " << mCookie << LL_ENDL;
   7.306 -	}
   7.307 -	
   7.308 -	
   7.309 -	return true;
   7.310 -}
   7.311 -
   7.312 -std::string::size_type LLPluginCookieStore::Cookie::findFieldEnd(std::string::size_type start, std::string::size_type end)
   7.313 -{
   7.314 -	std::string::size_type result = start;
   7.315 -	
   7.316 -	if(end == std::string::npos)
   7.317 -		end = mCookie.size();
   7.318 -	
   7.319 -	bool in_quotes = false;
   7.320 -	for(; (result < end); result++)
   7.321 -	{
   7.322 -		switch(mCookie[result])
   7.323 -		{
   7.324 -			case '\\':
   7.325 -				if(in_quotes)
   7.326 -					result++; // The next character is backslash-quoted.  Skip over it.
   7.327 -			break;
   7.328 -			case '"':
   7.329 -				in_quotes = !in_quotes;
   7.330 -			break;
   7.331 -			case ';':
   7.332 -				if(!in_quotes)
   7.333 -					return result;
   7.334 -			break;
   7.335 -		}		
   7.336 -	}
   7.337 -	
   7.338 -	// If we got here, no ';' was found.
   7.339 -	return end;
   7.340 -}
   7.341 -
   7.342 -bool LLPluginCookieStore::Cookie::matchName(std::string::size_type start, std::string::size_type end, const char *name)
   7.343 -{
   7.344 -	// NOTE: this assumes 'name' is already in lowercase.  The code which uses it should be able to arrange this...
   7.345 -	
   7.346 -	while((start < end) && (*name != '\0'))
   7.347 -	{
   7.348 -		if(tolower(mCookie[start]) != *name)
   7.349 -			return false;
   7.350 -			
   7.351 -		start++;
   7.352 -		name++;
   7.353 -	}
   7.354 -	
   7.355 -	// iff both strings hit the end at the same time, they're equal.
   7.356 -	return ((start == end) && (*name == '\0'));
   7.357 -}
   7.358 -
   7.359 -std::string LLPluginCookieStore::getAllCookies()
   7.360 -{
   7.361 -	std::stringstream result;
   7.362 -	writeAllCookies(result);
   7.363 -	return result.str();
   7.364 -}
   7.365 -
   7.366 -void LLPluginCookieStore::writeAllCookies(std::ostream& s)
   7.367 -{
   7.368 -	cookie_map_t::iterator iter;
   7.369 -	for(iter = mCookies.begin(); iter != mCookies.end(); iter++)
   7.370 -	{
   7.371 -		// Don't return expired cookies
   7.372 -		if(!iter->second->isDead())
   7.373 -		{
   7.374 -			s << (iter->second->getCookie()) << "\n";
   7.375 -		}
   7.376 -	}
   7.377 -
   7.378 -}
   7.379 -
   7.380 -std::string LLPluginCookieStore::getPersistentCookies()
   7.381 -{
   7.382 -	std::stringstream result;
   7.383 -	writePersistentCookies(result);
   7.384 -	return result.str();
   7.385 -}
   7.386 -
   7.387 -void LLPluginCookieStore::writePersistentCookies(std::ostream& s)
   7.388 -{
   7.389 -	cookie_map_t::iterator iter;
   7.390 -	for(iter = mCookies.begin(); iter != mCookies.end(); iter++)
   7.391 -	{
   7.392 -		// Don't return expired cookies or session cookies
   7.393 -		if(!iter->second->isDead() && !iter->second->isSessionCookie())
   7.394 -		{
   7.395 -			s << iter->second->getCookie() << "\n";
   7.396 -		}
   7.397 -	}
   7.398 -}
   7.399 -
   7.400 -std::string LLPluginCookieStore::getChangedCookies(bool clear_changed)
   7.401 -{
   7.402 -	std::stringstream result;
   7.403 -	writeChangedCookies(result, clear_changed);
   7.404 -	
   7.405 -	return result.str();
   7.406 -}
   7.407 -
   7.408 -void LLPluginCookieStore::writeChangedCookies(std::ostream& s, bool clear_changed)
   7.409 -{
   7.410 -	if(mHasChangedCookies)
   7.411 -	{
   7.412 -		LL_DEBUGS() << "returning changed cookies: " << LL_ENDL;
   7.413 -		cookie_map_t::iterator iter;
   7.414 -		for(iter = mCookies.begin(); iter != mCookies.end(); )
   7.415 -		{
   7.416 -			cookie_map_t::iterator next = iter;
   7.417 -			next++;
   7.418 -			
   7.419 -			// Only return cookies marked as "changed"
   7.420 -			if(iter->second->isChanged())
   7.421 -			{
   7.422 -				s << iter->second->getCookie() << "\n";
   7.423 -
   7.424 -				LL_DEBUGS() << "    " << iter->second->getCookie() << LL_ENDL;
   7.425 -
   7.426 -				// If requested, clear the changed mark
   7.427 -				if(clear_changed)
   7.428 -				{
   7.429 -					if(iter->second->isDead())
   7.430 -					{
   7.431 -						// If this cookie was previously marked dead, it needs to be removed entirely.	
   7.432 -						delete iter->second;
   7.433 -						mCookies.erase(iter);
   7.434 -					}
   7.435 -					else
   7.436 -					{
   7.437 -						// Not dead, just mark as not changed.
   7.438 -						iter->second->setChanged(false);
   7.439 -					}
   7.440 -				}
   7.441 -			}
   7.442 -			
   7.443 -			iter = next;
   7.444 -		}
   7.445 -	}
   7.446 -	
   7.447 -	if(clear_changed)
   7.448 -		mHasChangedCookies = false;
   7.449 -}
   7.450 -
   7.451 -void LLPluginCookieStore::setAllCookies(const std::string &cookies, bool mark_changed)
   7.452 -{
   7.453 -	clearCookies();
   7.454 -	setCookies(cookies, mark_changed);
   7.455 -}
   7.456 -
   7.457 -void LLPluginCookieStore::readAllCookies(std::istream& s, bool mark_changed)
   7.458 -{
   7.459 -	clearCookies();
   7.460 -	readCookies(s, mark_changed);
   7.461 -}
   7.462 -	
   7.463 -void LLPluginCookieStore::setCookies(const std::string &cookies, bool mark_changed)
   7.464 -{
   7.465 -	std::string::size_type start = 0;
   7.466 -
   7.467 -	while(start != std::string::npos)
   7.468 -	{
   7.469 -		std::string::size_type end = cookies.find_first_of("\r\n", start);
   7.470 -		if(end > start)
   7.471 -		{
   7.472 -			// The line is non-empty.  Try to create a cookie from it.
   7.473 -			setOneCookie(cookies, start, end, mark_changed);
   7.474 -		}
   7.475 -		start = cookies.find_first_not_of("\r\n ", end);
   7.476 -	}
   7.477 -}
   7.478 -
   7.479 -void LLPluginCookieStore::setCookiesFromHost(const std::string &cookies, const std::string &host, bool mark_changed)
   7.480 -{
   7.481 -	std::string::size_type start = 0;
   7.482 -
   7.483 -	while(start != std::string::npos)
   7.484 -	{
   7.485 -		std::string::size_type end = cookies.find_first_of("\r\n", start);
   7.486 -		if(end > start)
   7.487 -		{
   7.488 -			// The line is non-empty.  Try to create a cookie from it.
   7.489 -			setOneCookie(cookies, start, end, mark_changed, host);
   7.490 -		}
   7.491 -		start = cookies.find_first_not_of("\r\n ", end);
   7.492 -	}
   7.493 -}
   7.494 -			
   7.495 -void LLPluginCookieStore::readCookies(std::istream& s, bool mark_changed)
   7.496 -{
   7.497 -	std::string line;
   7.498 -	while(s.good() && !s.eof())
   7.499 -	{
   7.500 -		std::getline(s, line);
   7.501 -		if(!line.empty())
   7.502 -		{
   7.503 -			// Try to create a cookie from this line.
   7.504 -			setOneCookie(line, 0, std::string::npos, mark_changed);
   7.505 -		}
   7.506 -	}
   7.507 -}
   7.508 -
   7.509 -std::string LLPluginCookieStore::quoteString(const std::string &s)
   7.510 -{
   7.511 -	std::stringstream result;
   7.512 -	
   7.513 -	result << '"';
   7.514 -	
   7.515 -	for(std::string::size_type i = 0; i < s.size(); ++i)
   7.516 -	{
   7.517 -		char c = s[i];
   7.518 -		switch(c)
   7.519 -		{
   7.520 -			// All these separators need to be quoted in HTTP headers, according to section 2.2 of rfc 2616:
   7.521 -			case '(': case ')': case '<': case '>': case '@':
   7.522 -			case ',': case ';': case ':': case '\\': case '"':
   7.523 -			case '/': case '[': case ']': case '?': case '=':
   7.524 -			case '{': case '}':	case ' ': case '\t':
   7.525 -				result << '\\';
   7.526 -			break;
   7.527 -		}
   7.528 -		
   7.529 -		result << c;
   7.530 -	}
   7.531 -	
   7.532 -	result << '"';
   7.533 -	
   7.534 -	return result.str();
   7.535 -}
   7.536 -
   7.537 -std::string LLPluginCookieStore::unquoteString(const std::string &s)
   7.538 -{
   7.539 -	std::stringstream result;
   7.540 -	
   7.541 -	bool in_quotes = false;
   7.542 -	
   7.543 -	for(std::string::size_type i = 0; i < s.size(); ++i)
   7.544 -	{
   7.545 -		char c = s[i];
   7.546 -		switch(c)
   7.547 -		{
   7.548 -			case '\\':
   7.549 -				if(in_quotes)
   7.550 -				{
   7.551 -					// The next character is backslash-quoted.  Pass it through untouched.
   7.552 -					++i; 
   7.553 -					if(i < s.size())
   7.554 -					{
   7.555 -						result << s[i];
   7.556 -					}
   7.557 -					continue;
   7.558 -				}
   7.559 -			break;
   7.560 -			case '"':
   7.561 -				in_quotes = !in_quotes;
   7.562 -				continue;
   7.563 -			break;
   7.564 -		}
   7.565 -		
   7.566 -		result << c;
   7.567 -	}
   7.568 -	
   7.569 -	return result.str();
   7.570 -}
   7.571 -
   7.572 -// The flow for deleting a cookie is non-obvious enough that I should call it out here...
   7.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.
   7.574 -// (This is exactly how a web server tells a browser to delete a cookie.)
   7.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.
   7.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
   7.577 -// delete operation (in the form of the expired cookie) is passed along.
   7.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)
   7.579 -{
   7.580 -	Cookie *cookie = Cookie::createFromString(s, cookie_start, cookie_end, host);
   7.581 -	if(cookie)
   7.582 -	{
   7.583 -		LL_DEBUGS("CookieStoreUpdate") << "setting cookie: " << cookie->getCookie() << LL_ENDL;
   7.584 -		
   7.585 -		// Create a key for this cookie
   7.586 -		std::string key = cookie->getKey();
   7.587 -		
   7.588 -		// Check to see whether this cookie should have expired
   7.589 -		if(!cookie->isSessionCookie() && (cookie->getDate() < LLDate::now()))
   7.590 -		{
   7.591 -			// This cookie has expired.
   7.592 -			if(mark_changed)
   7.593 -			{
   7.594 -				// If we're marking cookies as changed, we should keep it anyway since we'll need to send it out with deltas.
   7.595 -				cookie->setDead(true);
   7.596 -				LL_DEBUGS("CookieStoreUpdate") << "    marking dead" << LL_ENDL;
   7.597 -			}
   7.598 -			else
   7.599 -			{
   7.600 -				// If we're not marking cookies as changed, we don't need to keep this cookie at all.
   7.601 -				// If the cookie was already in the list, delete it.
   7.602 -				removeCookie(key);
   7.603 -
   7.604 -				delete cookie;
   7.605 -				cookie = NULL;
   7.606 -
   7.607 -				LL_DEBUGS("CookieStoreUpdate") << "    removing" << LL_ENDL;
   7.608 -			}
   7.609 -		}
   7.610 -		
   7.611 -		if(cookie)
   7.612 -		{
   7.613 -			// If it already exists in the map, replace it.
   7.614 -			cookie_map_t::iterator iter = mCookies.find(key);
   7.615 -			if(iter != mCookies.end())
   7.616 -			{
   7.617 -				if(iter->second->getCookie() == cookie->getCookie())
   7.618 -				{
   7.619 -					// The new cookie is identical to the old -- don't mark as changed.
   7.620 -					// Just leave the old one in the map.
   7.621 -					delete cookie;
   7.622 -					cookie = NULL;
   7.623 -
   7.624 -					LL_DEBUGS("CookieStoreUpdate") << "    unchanged" << LL_ENDL;
   7.625 -				}
   7.626 -				else
   7.627 -				{
   7.628 -					// A matching cookie was already in the map.  Replace it.
   7.629 -					delete iter->second;
   7.630 -					iter->second = cookie;
   7.631 -					
   7.632 -					cookie->setChanged(mark_changed);
   7.633 -					if(mark_changed)
   7.634 -						mHasChangedCookies = true;
   7.635 -
   7.636 -					LL_DEBUGS("CookieStoreUpdate") << "    replacing" << LL_ENDL;
   7.637 -				}
   7.638 -			}
   7.639 -			else
   7.640 -			{
   7.641 -				// The cookie wasn't in the map.  Insert it.
   7.642 -				mCookies.insert(std::make_pair(key, cookie));
   7.643 -				
   7.644 -				cookie->setChanged(mark_changed);
   7.645 -				if(mark_changed)
   7.646 -					mHasChangedCookies = true;
   7.647 -
   7.648 -				LL_DEBUGS("CookieStoreUpdate") << "    adding" << LL_ENDL;
   7.649 -			}
   7.650 -		}
   7.651 -	}
   7.652 -	else
   7.653 -	{
   7.654 -		LL_WARNS("CookieStoreUpdate") << "failed to parse cookie: " << s.substr(cookie_start, cookie_end - cookie_start) << LL_ENDL;
   7.655 -	}
   7.656 -
   7.657 -}
   7.658 -
   7.659 -void LLPluginCookieStore::clearCookies()
   7.660 -{
   7.661 -	std::for_each(mCookies.begin(), mCookies.end(), DeletePairedPointer());
   7.662 -	mCookies.clear();
   7.663 -}
   7.664 -
   7.665 -void LLPluginCookieStore::removeCookie(const std::string &key)
   7.666 -{
   7.667 -	cookie_map_t::iterator iter = mCookies.find(key);
   7.668 -	if(iter != mCookies.end())
   7.669 -	{
   7.670 -		delete iter->second;
   7.671 -		mCookies.erase(iter);
   7.672 -	}
   7.673 -}
   7.674 -
   7.675 -void LLPluginCookieStore::removeCookiesByDomain(const std::string &domain)
   7.676 -{
   7.677 -	cookie_map_t::iterator iter = mCookies.begin();
   7.678 -	while(iter != mCookies.end())
   7.679 -	{ 
   7.680 -		if(iter->second->getDomain() == domain)
   7.681 -		{
   7.682 -            cookie_map_t::iterator doErase = iter;
   7.683 -            iter++;
   7.684 -			delete doErase->second;
   7.685 -			mCookies.erase(doErase);
   7.686 -		}
   7.687 -        else
   7.688 -        {
   7.689 -            iter++;
   7.690 -        }
   7.691 -	}
   7.692 -}
     8.1 --- a/indra/llplugin/llplugincookiestore.h	Fri Apr 06 14:15:11 2018 +0000
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,123 +0,0 @@
     8.4 -/** 
     8.5 - * @file llplugincookiestore.h
     8.6 - * @brief LLPluginCookieStore provides central storage for http cookies used by plugins
     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 -#ifndef LL_LLPLUGINCOOKIESTORE_H
    8.33 -#define LL_LLPLUGINCOOKIESTORE_H
    8.34 -
    8.35 -#include "lldate.h"
    8.36 -#include <map>
    8.37 -#include <string>
    8.38 -#include <iostream>
    8.39 -
    8.40 -class LLPluginCookieStore
    8.41 -{
    8.42 -	LOG_CLASS(LLPluginCookieStore);
    8.43 -public:
    8.44 -	LLPluginCookieStore();
    8.45 -	~LLPluginCookieStore();
    8.46 -
    8.47 -	// gets all cookies currently in storage -- use when initializing a plugin
    8.48 -	std::string getAllCookies();
    8.49 -	void writeAllCookies(std::ostream& s);
    8.50 -	
    8.51 -	// gets only persistent cookies (i.e. not session cookies) -- use when writing cookies to a file
    8.52 -	std::string getPersistentCookies();
    8.53 -	void writePersistentCookies(std::ostream& s);
    8.54 -	
    8.55 -	// gets cookies which are marked as "changed" -- use when sending periodic updates to plugins
    8.56 -	std::string getChangedCookies(bool clear_changed = true);
    8.57 -	void writeChangedCookies(std::ostream& s, bool clear_changed = true);
    8.58 -	
    8.59 -	// (re)initializes internal data structures and bulk-sets cookies -- use when reading cookies from a file
    8.60 -	void setAllCookies(const std::string &cookies, bool mark_changed = false);
    8.61 -	void readAllCookies(std::istream& s, bool mark_changed = false);
    8.62 -	
    8.63 -	// sets one or more cookies (without reinitializing anything) -- use when receiving cookies from a plugin
    8.64 -	void setCookies(const std::string &cookies, bool mark_changed = true);
    8.65 -	void readCookies(std::istream& s, bool mark_changed = true);
    8.66 -
    8.67 -	// sets one or more cookies (without reinitializing anything), supplying a hostname the cookies came from -- use when setting a cookie manually
    8.68 -	void setCookiesFromHost(const std::string &cookies, const std::string &host, bool mark_changed = true);
    8.69 -
    8.70 -	// quote or unquote a string as per the definition of 'quoted-string' in rfc2616
    8.71 -	static std::string quoteString(const std::string &s);
    8.72 -	static std::string unquoteString(const std::string &s);
    8.73 -
    8.74 -	void removeCookiesByDomain(const std::string &domain);
    8.75 -	
    8.76 -private:
    8.77 -
    8.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);
    8.79 -
    8.80 -	class Cookie
    8.81 -	{
    8.82 -	public:
    8.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);
    8.84 -		
    8.85 -		// Construct a string from the cookie that uniquely represents it, to be used as a key in a std::map.
    8.86 -		std::string getKey() const;
    8.87 -		std::string getDomain() const;
    8.88 -		
    8.89 -		const std::string &getCookie() const { return mCookie; };
    8.90 -		bool isSessionCookie() const { return mDate.isNull(); };
    8.91 -
    8.92 -		bool isDead() const { return mDead; };
    8.93 -		void setDead(bool dead) { mDead = dead; };
    8.94 -		
    8.95 -		bool isChanged() const { return mChanged; };
    8.96 -		void setChanged(bool changed) { mChanged = changed; };
    8.97 -
    8.98 -		const LLDate &getDate() const { return mDate; };
    8.99 -		
   8.100 -	private:
   8.101 -		Cookie(const std::string &s, std::string::size_type cookie_start = 0, std::string::size_type cookie_end = std::string::npos);
   8.102 -		bool parse(const std::string &host);
   8.103 -		std::string::size_type findFieldEnd(std::string::size_type start = 0, std::string::size_type end = std::string::npos);
   8.104 -		bool matchName(std::string::size_type start, std::string::size_type end, const char *name);
   8.105 -		
   8.106 -		std::string mCookie;	// The full cookie, in RFC 2109 string format
   8.107 -		LLDate mDate;			// The expiration date of the cookie.  For session cookies, this will be a null date (mDate.isNull() is true).
   8.108 -		// Start/end indices of various parts of the cookie string.  Stored as indices into the string to save space and time.
   8.109 -		std::string::size_type mNameStart, mNameEnd;
   8.110 -		std::string::size_type mValueStart, mValueEnd;
   8.111 -		std::string::size_type mDomainStart, mDomainEnd;
   8.112 -		std::string::size_type mPathStart, mPathEnd;
   8.113 -		bool mDead;
   8.114 -		bool mChanged;
   8.115 -	};
   8.116 -	
   8.117 -	typedef std::map<std::string, Cookie*> cookie_map_t;
   8.118 -	
   8.119 -	cookie_map_t mCookies;
   8.120 -	bool mHasChangedCookies;
   8.121 -	
   8.122 -	void clearCookies();
   8.123 -	void removeCookie(const std::string &key);
   8.124 -};
   8.125 -
   8.126 -#endif // LL_LLPLUGINCOOKIESTORE_H
     9.1 --- a/indra/llplugin/tests/llplugincookiestore_test.cpp	Fri Apr 06 14:15:11 2018 +0000
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,207 +0,0 @@
     9.4 -/** 
     9.5 - * @file llplugincookiestore_test.cpp
     9.6 - * @brief Unit tests for LLPluginCookieStore.
     9.7 - *
     9.8 - * @cond
     9.9 - * $LicenseInfo:firstyear=2010&license=viewerlgpl$
    9.10 - * Second Life Viewer Source Code
    9.11 - * Copyright (C) 2010, Linden Research, Inc.
    9.12 - * 
    9.13 - * This library is free software; you can redistribute it and/or
    9.14 - * modify it under the terms of the GNU Lesser General Public
    9.15 - * License as published by the Free Software Foundation;
    9.16 - * version 2.1 of the License only.
    9.17 - * 
    9.18 - * This library is distributed in the hope that it will be useful,
    9.19 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    9.20 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    9.21 - * Lesser General Public License for more details.
    9.22 - * 
    9.23 - * You should have received a copy of the GNU Lesser General Public
    9.24 - * License along with this library; if not, write to the Free Software
    9.25 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
    9.26 - * 
    9.27 - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
    9.28 - * $/LicenseInfo$
    9.29 - * @endcond
    9.30 - */
    9.31 -
    9.32 -#include "linden_common.h"
    9.33 -#include <list>
    9.34 -#include "../test/lltut.h"
    9.35 -
    9.36 -#include "../llplugincookiestore.h"
    9.37 -
    9.38 -
    9.39 -namespace tut
    9.40 -{
    9.41 -	// Main Setup
    9.42 -	struct LLPluginCookieStoreFixture
    9.43 -	{
    9.44 -		LLPluginCookieStoreFixture()
    9.45 -		{
    9.46 -			// We need dates definitively in the past and the future to properly test cookie expiration.
    9.47 -			LLDate now = LLDate::now(); 
    9.48 -			LLDate past(now.secondsSinceEpoch() - (60.0 * 60.0 * 24.0));	// 1 day in the past
    9.49 -			LLDate future(now.secondsSinceEpoch() + (60.0 * 60.0 * 24.0));	// 1 day in the future
    9.50 -			
    9.51 -			mPastString = past.asRFC1123();
    9.52 -			mFutureString = future.asRFC1123();
    9.53 -		}
    9.54 -		
    9.55 -		std::string mPastString;
    9.56 -		std::string mFutureString;
    9.57 -		LLPluginCookieStore mCookieStore;
    9.58 -		
    9.59 -		// List of cookies used for validation
    9.60 -		std::list<std::string> mCookies;
    9.61 -		
    9.62 -		// This sets up mCookies from a string returned by one of the functions in LLPluginCookieStore
    9.63 -		void setCookies(const std::string &cookies)
    9.64 -		{
    9.65 -			mCookies.clear();
    9.66 -			std::string::size_type start = 0;
    9.67 -
    9.68 -			while(start != std::string::npos)
    9.69 -			{
    9.70 -				std::string::size_type end = cookies.find_first_of("\r\n", start);
    9.71 -				if(end > start)
    9.72 -				{
    9.73 -					std::string line(cookies, start, end - start);
    9.74 -					if(line.find_first_not_of("\r\n\t ") != std::string::npos)
    9.75 -					{
    9.76 -						// The line has some non-whitespace characters.  Save it to the list.
    9.77 -						mCookies.push_back(std::string(cookies, start, end - start));
    9.78 -					}
    9.79 -				}
    9.80 -				start = cookies.find_first_not_of("\r\n ", end);
    9.81 -			}
    9.82 -		}
    9.83 -		
    9.84 -		// This ensures that a cookie matching the one passed is in the list.
    9.85 -		void ensureCookie(const std::string &cookie)
    9.86 -		{
    9.87 -			std::list<std::string>::iterator iter;
    9.88 -			for(iter = mCookies.begin(); iter != mCookies.end(); iter++)
    9.89 -			{
    9.90 -				if(*iter == cookie)
    9.91 -				{
    9.92 -					// Found the cookie
    9.93 -					// TODO: this should do a smarter equality comparison on the two cookies, instead of just a string compare.
    9.94 -					return;
    9.95 -				}
    9.96 -			}
    9.97 -			
    9.98 -			// Didn't find this cookie
    9.99 -			std::string message = "cookie not found: ";
   9.100 -			message += cookie;
   9.101 -			ensure(message, false);
   9.102 -		}
   9.103 -		
   9.104 -		// This ensures that the number of cookies in the list matches what's expected.
   9.105 -		void ensureSize(const std::string &message, size_t size)
   9.106 -		{
   9.107 -			if(mCookies.size() != size)
   9.108 -			{
   9.109 -				std::stringstream full_message;
   9.110 -				
   9.111 -				full_message << message << " (expected " << size << ", actual " << mCookies.size() << ")";
   9.112 -				ensure(full_message.str(), false);
   9.113 -			}
   9.114 -		}
   9.115 -	};
   9.116 -	
   9.117 -	typedef test_group<LLPluginCookieStoreFixture> factory;
   9.118 -	typedef factory::object object;
   9.119 -	factory tf("LLPluginCookieStore");
   9.120 -
   9.121 -	// Tests
   9.122 -	template<> template<>
   9.123 -	void object::test<1>()
   9.124 -	{
   9.125 -		// Test 1: cookie uniqueness and update lists.
   9.126 -		// Valid, distinct cookies:
   9.127 -		
   9.128 -		std::string cookie01 = "cookieA=value; domain=example.com; path=/";
   9.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.
   9.130 -		std::string cookie03 = "cookieA=value; domain=foo.example.com; path=/"; // different domain
   9.131 -		std::string cookie04 = "cookieA=value; domain=example.com; path=/bar/"; // different path
   9.132 -		std::string cookie05 = "cookieC; domain=example.com; path=/"; // empty value
   9.133 -		std::string cookie06 = "cookieD=value; domain=example.com; path=/; expires="; // different name, persistent cookie
   9.134 -		cookie06 += mFutureString;
   9.135 -		
   9.136 -		mCookieStore.setCookies(cookie01);
   9.137 -		mCookieStore.setCookies(cookie02);
   9.138 -		mCookieStore.setCookies(cookie03);
   9.139 -		mCookieStore.setCookies(cookie04);
   9.140 -		mCookieStore.setCookies(cookie05);
   9.141 -		mCookieStore.setCookies(cookie06);
   9.142 -		
   9.143 -		// Invalid cookies (these will get parse errors and not be added to the store)
   9.144 -
   9.145 -		std::string badcookie01 = "cookieD=value; domain=example.com; path=/; foo=bar"; // invalid field name
   9.146 -		std::string badcookie02 = "cookieE=value; path=/"; // no domain
   9.147 -
   9.148 -		mCookieStore.setCookies(badcookie01);
   9.149 -		mCookieStore.setCookies(badcookie02);
   9.150 -		
   9.151 -		// All cookies added so far should have been marked as "changed"
   9.152 -		setCookies(mCookieStore.getChangedCookies());
   9.153 -		ensureSize("count of changed cookies", 6);
   9.154 -		ensureCookie(cookie01);
   9.155 -		ensureCookie(cookie02);
   9.156 -		ensureCookie(cookie03);
   9.157 -		ensureCookie(cookie04);
   9.158 -		ensureCookie(cookie05);
   9.159 -		ensureCookie(cookie06);
   9.160 -		
   9.161 -		// Save off the current state of the cookie store (we'll restore it later)
   9.162 -		std::string savedCookies = mCookieStore.getAllCookies();
   9.163 -		
   9.164 -		// Test replacing cookies
   9.165 -		std::string cookie01a = "cookieA=newvalue; domain=example.com; path=/";	// updated value
   9.166 -		std::string cookie02a = "cookieB=newvalue; domain=example.com; path=/; expires="; // remove cookie (by setting an expire date in the past)
   9.167 -		cookie02a += mPastString;
   9.168 -		
   9.169 -		mCookieStore.setCookies(cookie01a);
   9.170 -		mCookieStore.setCookies(cookie02a);
   9.171 -
   9.172 -		// test for getting changed cookies
   9.173 -		setCookies(mCookieStore.getChangedCookies());
   9.174 -		ensureSize("count of updated cookies", 2);
   9.175 -		ensureCookie(cookie01a);
   9.176 -		ensureCookie(cookie02a);
   9.177 -		
   9.178 -		// and for the state of the store after getting changed cookies
   9.179 -		setCookies(mCookieStore.getAllCookies());
   9.180 -		ensureSize("count of valid cookies", 5);
   9.181 -		ensureCookie(cookie01a);
   9.182 -		ensureCookie(cookie03);
   9.183 -		ensureCookie(cookie04);
   9.184 -		ensureCookie(cookie05);
   9.185 -		ensureCookie(cookie06);
   9.186 -
   9.187 -		// Check that only the persistent cookie is returned here
   9.188 -		setCookies(mCookieStore.getPersistentCookies());
   9.189 -		ensureSize("count of persistent cookies", 1);
   9.190 -		ensureCookie(cookie06);
   9.191 -
   9.192 -		// Restore the cookie store to a previous state and verify
   9.193 -		mCookieStore.setAllCookies(savedCookies);
   9.194 -		
   9.195 -		// Since setAllCookies defaults to not marking cookies as changed, this list should be empty.
   9.196 -		setCookies(mCookieStore.getChangedCookies());
   9.197 -		ensureSize("count of changed cookies after restore", 0);
   9.198 -
   9.199 -		// Verify that the restore worked as it should have.
   9.200 -		setCookies(mCookieStore.getAllCookies());
   9.201 -		ensureSize("count of restored cookies", 6);
   9.202 -		ensureCookie(cookie01);
   9.203 -		ensureCookie(cookie02);
   9.204 -		ensureCookie(cookie03);
   9.205 -		ensureCookie(cookie04);
   9.206 -		ensureCookie(cookie05);
   9.207 -		ensureCookie(cookie06);
   9.208 -	}
   9.209 -
   9.210 -}
    10.1 --- a/indra/media_plugins/cef/media_plugin_cef.cpp	Fri Apr 06 14:15:11 2018 +0000
    10.2 +++ b/indra/media_plugins/cef/media_plugin_cef.cpp	Thu Apr 12 21:22:22 2018 +0300
    10.3 @@ -38,6 +38,7 @@
    10.4  #include "media_plugin_base.h"
    10.5  
    10.6  #include <functional>
    10.7 +#include <chrono>
    10.8  
    10.9  #include "dullahan.h"
   10.10  
   10.11 @@ -64,12 +65,12 @@
   10.12  	void onLoadStartCallback();
   10.13  	void onRequestExitCallback();
   10.14  	void onLoadEndCallback(int httpStatusCode);
   10.15 +	void onLoadError(int status, const std::string error_text);
   10.16  	void onAddressChangeCallback(std::string url);
   10.17 -	void onNavigateURLCallback(std::string url, std::string target);
   10.18 +	void onOpenPopupCallback(std::string url, std::string target);
   10.19  	bool onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password);
   10.20  	void onCursorChangedCallback(dullahan::ECursorType type);
   10.21 -	void onFileDownloadCallback(std::string filename);
   10.22 -	const std::string onFileDialogCallback();
   10.23 +	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);
   10.24  
   10.25  	void postDebugMessage(const std::string& msg);
   10.26  	void authResponse(LLPluginMessage &message);
   10.27 @@ -95,7 +96,9 @@
   10.28  	bool mCanPaste;
   10.29  	std::string mCachePath;
   10.30  	std::string mCookiePath;
   10.31 -	std::string mPickedFile;
   10.32 +	std::string mCefLogFile;
   10.33 +	bool mCefLogVerbose;
   10.34 +	std::vector<std::string> mPickedFiles;
   10.35  	VolumeCatcher mVolumeCatcher;
   10.36  	F32 mCurVolume;
   10.37  	dullahan* mCEFLib;
   10.38 @@ -115,7 +118,7 @@
   10.39  	mCookiesEnabled = true;
   10.40  	mPluginsEnabled = false;
   10.41  	mJavascriptEnabled = true;
   10.42 -	mDisableGPU = true;
   10.43 +	mDisableGPU = false;
   10.44  	mUserAgentSubtring = "";
   10.45  	mAuthUsername = "";
   10.46  	mAuthPassword = "";
   10.47 @@ -125,7 +128,9 @@
   10.48  	mCanPaste = false;
   10.49  	mCachePath = "";
   10.50  	mCookiePath = "";
   10.51 -	mPickedFile = "";
   10.52 +	mCefLogFile = "";
   10.53 +	mCefLogVerbose = false;
   10.54 +	mPickedFiles.clear();
   10.55  	mCurVolume = 0.0;
   10.56  
   10.57  	mCEFLib = new dullahan();
   10.58 @@ -166,6 +171,10 @@
   10.59  		{
   10.60  			memcpy(mPixels, pixels, mWidth * mHeight * mDepth);
   10.61  		}
   10.62 +		else
   10.63 +		{
   10.64 +			mCEFLib->setSize(mWidth, mHeight);
   10.65 +		}
   10.66  		setDirty(0, 0, mWidth, mHeight);
   10.67  	}
   10.68  }
   10.69 @@ -210,6 +219,21 @@
   10.70  	sendMessage(message);
   10.71  }
   10.72  
   10.73 +/////////////////////////////////////////////////////////////////////////////////
   10.74 +//
   10.75 +void MediaPluginCEF::onLoadError(int status, const std::string error_text)
   10.76 +{
   10.77 +	std::stringstream msg;
   10.78 +
   10.79 +	msg << "<b>Loading error!</b>";
   10.80 +	msg << "<p>";
   10.81 +	msg << "Message: " << error_text;
   10.82 +	msg << "<br>";
   10.83 +	msg << "Code: " << status;
   10.84 +
   10.85 +	mCEFLib->showBrowserMessage(msg.str());
   10.86 +}
   10.87 +
   10.88  ////////////////////////////////////////////////////////////////////////////////
   10.89  //
   10.90  void MediaPluginCEF::onRequestExitCallback()
   10.91 @@ -243,12 +267,11 @@
   10.92  
   10.93  ////////////////////////////////////////////////////////////////////////////////
   10.94  //
   10.95 -void MediaPluginCEF::onNavigateURLCallback(std::string url, std::string target)
   10.96 +void MediaPluginCEF::onOpenPopupCallback(std::string url, std::string target)
   10.97  {
   10.98  	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_href");
   10.99  	message.setValue("uri", url);
  10.100  	message.setValue("target", target);
  10.101 -	message.setValue("uuid", "");	// not used right now
  10.102  	sendMessage(message);
  10.103  }
  10.104  
  10.105 @@ -287,30 +310,52 @@
  10.106  
  10.107  ////////////////////////////////////////////////////////////////////////////////
  10.108  //
  10.109 -void MediaPluginCEF::onFileDownloadCallback(const std::string filename)
  10.110 +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)
  10.111  {
  10.112 -	mAuthOK = false;
  10.113 +	// do not use the default CEF file picker
  10.114 +	use_default = false;
  10.115  
  10.116 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "file_download");
  10.117 -	message.setValue("filename", filename);
  10.118 +	if (dialog_type == dullahan::FD_OPEN_FILE)
  10.119 +	{
  10.120 +		mPickedFiles.clear();
  10.121  
  10.122 -	sendMessage(message);
  10.123 +		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file");
  10.124 +		message.setValueBoolean("blocking_request", true);
  10.125 +		message.setValueBoolean("multiple_files", false);
  10.126 +
  10.127 +		sendMessage(message);
  10.128 +
  10.129 +		return mPickedFiles;
  10.130 +	}
  10.131 +	else if (dialog_type == dullahan::FD_OPEN_MULTIPLE_FILES)
  10.132 +	{
  10.133 +		mPickedFiles.clear();
  10.134 +
  10.135 +		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file");
  10.136 +		message.setValueBoolean("blocking_request", true);
  10.137 +		message.setValueBoolean("multiple_files", true);
  10.138 +
  10.139 +		sendMessage(message);
  10.140 +
  10.141 +		return mPickedFiles;
  10.142 +	}
  10.143 +	else if (dialog_type == dullahan::FD_SAVE_FILE)
  10.144 +	{
  10.145 +		mAuthOK = false;
  10.146 +
  10.147 +		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "file_download");
  10.148 +		message.setValue("filename", default_file);
  10.149 +
  10.150 +		sendMessage(message);
  10.151 +
  10.152 +		return std::vector<std::string>();
  10.153 +	}
  10.154 +
  10.155 +	return std::vector<std::string>();
  10.156  }
  10.157  
  10.158  ////////////////////////////////////////////////////////////////////////////////
  10.159  //
  10.160 -const std::string MediaPluginCEF::onFileDialogCallback()
  10.161 -{
  10.162 -	mPickedFile.clear();
  10.163 -
  10.164 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file");
  10.165 -	message.setValueBoolean("blocking_request", true);
  10.166 -
  10.167 -	sendMessage(message);
  10.168 -
  10.169 -	return mPickedFile;
  10.170 -}
  10.171 -
  10.172  void MediaPluginCEF::onCursorChangedCallback(dullahan::ECursorType type)
  10.173  {
  10.174  	std::string name = "";
  10.175 @@ -343,6 +388,8 @@
  10.176  	sendMessage(message);
  10.177  }
  10.178  
  10.179 +////////////////////////////////////////////////////////////////////////////////
  10.180 +//
  10.181  void MediaPluginCEF::authResponse(LLPluginMessage &message)
  10.182  {
  10.183  	mAuthOK = message.getValueBoolean("ok");
  10.184 @@ -375,7 +422,7 @@
  10.185  				versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION;
  10.186  				message.setValueLLSD("versions", versions);
  10.187  
  10.188 -				std::string plugin_version = "CEF plugin 1.1.3";
  10.189 +				std::string plugin_version = "CEF plugin 1.1.412";
  10.190  				message.setValue("plugin_version", plugin_version);
  10.191  				sendMessage(message);
  10.192  			}
  10.193 @@ -441,17 +488,17 @@
  10.194  				mCEFLib->setOnTitleChangeCallback(std::bind(&MediaPluginCEF::onTitleChangeCallback, this, std::placeholders::_1));
  10.195  				mCEFLib->setOnLoadStartCallback(std::bind(&MediaPluginCEF::onLoadStartCallback, this));
  10.196  				mCEFLib->setOnLoadEndCallback(std::bind(&MediaPluginCEF::onLoadEndCallback, this, std::placeholders::_1));
  10.197 +				mCEFLib->setOnLoadErrorCallback(std::bind(&MediaPluginCEF::onLoadError, this, std::placeholders::_1, std::placeholders::_2));
  10.198  				mCEFLib->setOnAddressChangeCallback(std::bind(&MediaPluginCEF::onAddressChangeCallback, this, std::placeholders::_1));
  10.199 -				mCEFLib->setOnNavigateURLCallback(std::bind(&MediaPluginCEF::onNavigateURLCallback, this, std::placeholders::_1, std::placeholders::_2));
  10.200 +				mCEFLib->setOnOpenPopupCallback(std::bind(&MediaPluginCEF::onOpenPopupCallback, this, std::placeholders::_1, std::placeholders::_2));
  10.201  				mCEFLib->setOnHTTPAuthCallback(std::bind(&MediaPluginCEF::onHTTPAuthCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
  10.202 -				mCEFLib->setOnFileDownloadCallback(std::bind(&MediaPluginCEF::onFileDownloadCallback, this, std::placeholders::_1));
  10.203 -				mCEFLib->setOnFileDialogCallback(std::bind(&MediaPluginCEF::onFileDialogCallback, this));
  10.204 +				mCEFLib->setOnFileDialogCallback(std::bind(&MediaPluginCEF::onFileDialog, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
  10.205  				mCEFLib->setOnCursorChangedCallback(std::bind(&MediaPluginCEF::onCursorChangedCallback, this, std::placeholders::_1));
  10.206  				mCEFLib->setOnRequestExitCallback(std::bind(&MediaPluginCEF::onRequestExitCallback, this));
  10.207  
  10.208  				dullahan::dullahan_settings settings;
  10.209  				settings.accept_language_list = mHostLanguage;
  10.210 -				settings.background_color = 0xffffffff;
  10.211 +				settings.background_color = 0xff282828;
  10.212  				settings.cache_enabled = true;
  10.213  				settings.cache_path = mCachePath;
  10.214  				settings.cookie_store_path = mCookiePath;
  10.215 @@ -470,6 +517,8 @@
  10.216  				settings.plugins_enabled = mPluginsEnabled;
  10.217  				settings.user_agent_substring = mCEFLib->makeCompatibleUserAgentString(mUserAgentSubtring);
  10.218  				settings.webgl_enabled = true;
  10.219 +				settings.log_file = mCefLogFile;
  10.220 +				settings.log_verbose = mCefLogVerbose;
  10.221  
  10.222  				std::vector<std::string> custom_schemes(1, "secondlife");
  10.223  				mCEFLib->setCustomSchemes(custom_schemes);
  10.224 @@ -499,8 +548,11 @@
  10.225  			{
  10.226  				std::string user_data_path_cache = message_in.getValue("cache_path");
  10.227  				std::string user_data_path_cookies = message_in.getValue("cookies_path");
  10.228 +
  10.229  				mCachePath = user_data_path_cache + "cef_cache";
  10.230  				mCookiePath = user_data_path_cookies + "cef_cookies";
  10.231 +				mCefLogFile = message_in.getValue("cef_log_file");
  10.232 +				mCefLogVerbose = message_in.getValueBoolean("cef_verbose_log");
  10.233  			}
  10.234  			else if (message_name == "size_change")
  10.235  			{
  10.236 @@ -522,11 +574,11 @@
  10.237  
  10.238  						mTextureWidth = texture_width;
  10.239  						mTextureHeight = texture_height;
  10.240 +
  10.241 +						mCEFLib->setSize(mWidth, mHeight);
  10.242  					};
  10.243  				};
  10.244  
  10.245 -				mCEFLib->setSize(mWidth, mHeight);
  10.246 -
  10.247  				LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
  10.248  				message.setValue("name", name);
  10.249  				message.setValueS32("width", width);
  10.250 @@ -652,7 +704,14 @@
  10.251  			}
  10.252  			if (message_name == "pick_file_response")
  10.253  			{
  10.254 -				mPickedFile = message_in.getValue("file");
  10.255 +				LLSD file_list_llsd = message_in.getValueLLSD("file_list");
  10.256 +
  10.257 +				LLSD::array_const_iterator iter = file_list_llsd.beginArray();
  10.258 +				LLSD::array_const_iterator end = file_list_llsd.endArray();
  10.259 +				for (; iter != end; ++iter)
  10.260 +				{
  10.261 +					mPickedFiles.push_back(((*iter).asString()));
  10.262 +				}
  10.263  			}
  10.264  			if (message_name == "auth_response")
  10.265  			{
  10.266 @@ -699,6 +758,10 @@
  10.267  			{
  10.268  				mCookiesEnabled = message_in.getValueBoolean("enable");
  10.269  			}
  10.270 +			else if (message_name == "clear_cookies")
  10.271 +			{
  10.272 +				mCEFLib->deleteAllCookies();
  10.273 +			}
  10.274  			else if (message_name == "set_user_agent")
  10.275  			{
  10.276  				mUserAgentSubtring = message_in.getValue("user_agent");
    11.1 --- a/indra/newview/VIEWER_VERSION.txt	Fri Apr 06 14:15:11 2018 +0000
    11.2 +++ b/indra/newview/VIEWER_VERSION.txt	Thu Apr 12 21:22:22 2018 +0300
    11.3 @@ -1,1 +1,1 @@
    11.4 -5.1.3
    11.5 +5.1.4
    12.1 --- a/indra/newview/app_settings/settings.xml	Fri Apr 06 14:15:11 2018 +0000
    12.2 +++ b/indra/newview/app_settings/settings.xml	Thu Apr 12 21:22:22 2018 +0300
    12.3 @@ -16167,6 +16167,17 @@
    12.4        <key>Value</key>
    12.5        <integer>0</integer>
    12.6      </map>
    12.7 +    <key>CefVerboseLog</key>
    12.8 +    <map>
    12.9 +      <key>Comment</key>
   12.10 +      <string>Enable/disable CEF verbose loggingk</string>
   12.11 +      <key>Persist</key>
   12.12 +      <integer>1</integer>
   12.13 +      <key>Type</key>
   12.14 +      <string>Boolean</string>
   12.15 +      <key>Value</key>
   12.16 +      <integer>0</integer>
   12.17 +    </map>
   12.18  </map>
   12.19  </llsd>
   12.20  
    13.1 --- a/indra/newview/llappviewer.cpp	Fri Apr 06 14:15:11 2018 +0000
    13.2 +++ b/indra/newview/llappviewer.cpp	Thu Apr 12 21:22:22 2018 +0300
    13.3 @@ -1930,8 +1930,6 @@
    13.4  
    13.5  	LLAvatarIconIDCache::getInstance()->save();
    13.6  	
    13.7 -	LLViewerMedia::saveCookieFile();
    13.8 -
    13.9  	// Stop the plugin read thread if it's running.
   13.10  	LLPluginProcessParent::setUseReadThread(false);
   13.11  
   13.12 @@ -3166,8 +3164,14 @@
   13.13  	cef_ver_codec << " / CEF: ";
   13.14  	cef_ver_codec << CEF_VERSION;
   13.15  
   13.16 -	cef_ver_codec << " / Chrome: ";
   13.17 +	cef_ver_codec << " / Chromium: ";
   13.18  	cef_ver_codec << CHROME_VERSION_MAJOR;
   13.19 +	cef_ver_codec << ".";
   13.20 +	cef_ver_codec << CHROME_VERSION_MINOR;
   13.21 +	cef_ver_codec << ".";
   13.22 +	cef_ver_codec << CHROME_VERSION_BUILD;
   13.23 +	cef_ver_codec << ".";
   13.24 +	cef_ver_codec << CHROME_VERSION_PATCH;
   13.25  
   13.26  	info["LIBCEF_VERSION"] = cef_ver_codec.str();
   13.27  #else
    14.1 --- a/indra/newview/llfloaterfacebook.cpp	Fri Apr 06 14:15:11 2018 +0000
    14.2 +++ b/indra/newview/llfloaterfacebook.cpp	Thu Apr 12 21:22:22 2018 +0300
    14.3 @@ -1,4 +1,4 @@
    14.4 -/** 
    14.5 +/**
    14.6  * @file llfloaterfacebook.cpp
    14.7  * @brief Implementation of llfloaterfacebook
    14.8  * @author Gilbert@lindenlab.com
    14.9 @@ -41,7 +41,6 @@
   14.10  #include "llresmgr.h"		// LLLocale
   14.11  #include "llsdserialize.h"
   14.12  #include "llloadingindicator.h"
   14.13 -#include "llplugincookiestore.h"
   14.14  #include "llslurl.h"
   14.15  #include "lltrans.h"
   14.16  #include "llsnapshotlivepreview.h"
   14.17 @@ -296,16 +295,11 @@
   14.18  void LLFacebookStatusPanel::onConnect()
   14.19  {
   14.20      LLFacebookConnect::instance().checkConnectionToFacebook(true);
   14.21 -
   14.22 -    //Clear only the facebook browser cookies so that the facebook login screen appears
   14.23 -    LLViewerMedia::getCookieStore()->removeCookiesByDomain(".facebook.com");
   14.24  }
   14.25  
   14.26  void LLFacebookStatusPanel::onDisconnect()
   14.27  {
   14.28      LLFacebookConnect::instance().disconnectFromFacebook();
   14.29 -
   14.30 -    LLViewerMedia::getCookieStore()->removeCookiesByDomain(".facebook.com");
   14.31  }
   14.32  
   14.33  void LLFacebookStatusPanel::clearAndClose()
   14.34 @@ -810,7 +804,7 @@
   14.35      LLAgentUI::buildSLURL(slurl);
   14.36      std::string slurl_string = slurl.getSLURLString();
   14.37  
   14.38 -    // Use a valid http:// URL if the scheme is secondlife:// 
   14.39 +    // Use a valid http:// URL if the scheme is secondlife://
   14.40      LLURI slurl_uri(slurl_string);
   14.41      if (slurl_uri.scheme() == LLSLURL::SLURL_SECONDLIFE_SCHEME)
   14.42      {
    15.1 --- a/indra/newview/llfloaterflickr.cpp	Fri Apr 06 14:15:11 2018 +0000
    15.2 +++ b/indra/newview/llfloaterflickr.cpp	Thu Apr 12 21:22:22 2018 +0300
    15.3 @@ -40,7 +40,6 @@
    15.4  #include "llresmgr.h"		// LLLocale
    15.5  #include "llsdserialize.h"
    15.6  #include "llloadingindicator.h"
    15.7 -#include "llplugincookiestore.h"
    15.8  #include "llslurl.h"
    15.9  #include "lltrans.h"
   15.10  #include "llsnapshotlivepreview.h"
   15.11 @@ -660,16 +659,11 @@
   15.12  void LLFlickrAccountPanel::onConnect()
   15.13  {
   15.14  	LLFlickrConnect::instance().checkConnectionToFlickr(true);
   15.15 -
   15.16 -	//Clear only the flickr browser cookies so that the flickr login screen appears
   15.17 -	LLViewerMedia::getCookieStore()->removeCookiesByDomain(".flickr.com"); 
   15.18  }
   15.19  
   15.20  void LLFlickrAccountPanel::onDisconnect()
   15.21  {
   15.22  	LLFlickrConnect::instance().disconnectFromFlickr();
   15.23 -
   15.24 -	LLViewerMedia::getCookieStore()->removeCookiesByDomain(".flickr.com"); 
   15.25  }
   15.26  
   15.27  ////////////////////////
    16.1 --- a/indra/newview/llfloatertwitter.cpp	Fri Apr 06 14:15:11 2018 +0000
    16.2 +++ b/indra/newview/llfloatertwitter.cpp	Thu Apr 12 21:22:22 2018 +0300
    16.3 @@ -41,7 +41,6 @@
    16.4  #include "llresmgr.h"		// LLLocale
    16.5  #include "llsdserialize.h"
    16.6  #include "llloadingindicator.h"
    16.7 -#include "llplugincookiestore.h"
    16.8  #include "llslurl.h"
    16.9  #include "lltrans.h"
   16.10  #include "llsnapshotlivepreview.h"
   16.11 @@ -683,16 +682,11 @@
   16.12  void LLTwitterAccountPanel::onConnect()
   16.13  {
   16.14  	LLTwitterConnect::instance().checkConnectionToTwitter(true);
   16.15 -
   16.16 -	//Clear only the twitter browser cookies so that the twitter login screen appears
   16.17 -	LLViewerMedia::getCookieStore()->removeCookiesByDomain(".twitter.com"); 
   16.18  }
   16.19  
   16.20  void LLTwitterAccountPanel::onDisconnect()
   16.21  {
   16.22  	LLTwitterConnect::instance().disconnectFromTwitter();
   16.23 -
   16.24 -	LLViewerMedia::getCookieStore()->removeCookiesByDomain(".twitter.com"); 
   16.25  }
   16.26  
   16.27  ////////////////////////
    17.1 --- a/indra/newview/llmediactrl.cpp	Fri Apr 06 14:15:11 2018 +0000
    17.2 +++ b/indra/newview/llmediactrl.cpp	Thu Apr 12 21:22:22 2018 +0300
    17.3 @@ -1022,7 +1022,7 @@
    17.4  			// try as slurl first
    17.5  			if (!LLURLDispatcher::dispatch(url, "clicked", NULL, mTrusted))
    17.6  			{
    17.7 -				LLWeb::loadURL(url, target, std::string());
    17.8 +				LLWeb::loadURL(url, target, uuid);
    17.9  			}
   17.10  
   17.11  			// CP: removing this code because we no longer support popups so this breaks the flow.
    18.1 --- a/indra/newview/llstartup.cpp	Fri Apr 06 14:15:11 2018 +0000
    18.2 +++ b/indra/newview/llstartup.cpp	Thu Apr 12 21:22:22 2018 +0300
    18.3 @@ -972,9 +972,6 @@
    18.4  		// Load Avatars icons cache
    18.5  		LLAvatarIconIDCache::getInstance()->load();
    18.6  		
    18.7 -		// Load media plugin cookies
    18.8 -		LLViewerMedia::loadCookieFile();
    18.9 -
   18.10  		LLRenderMuteList::getInstance()->loadFromFile();
   18.11  
   18.12  		//-------------------------------------------------
    19.1 --- a/indra/newview/llviewermedia.cpp	Fri Apr 06 14:15:11 2018 +0000
    19.2 +++ b/indra/newview/llviewermedia.cpp	Thu Apr 12 21:22:22 2018 +0300
    19.3 @@ -50,7 +50,6 @@
    19.4  #include "llpanelprofile.h"
    19.5  #include "llparcel.h"
    19.6  #include "llpluginclassmedia.h"
    19.7 -#include "llplugincookiestore.h"
    19.8  #include "llurldispatcher.h"
    19.9  #include "lluuid.h"
   19.10  #include "llversioninfo.h"
   19.11 @@ -154,7 +153,6 @@
   19.12  }
   19.13  
   19.14  
   19.15 -LLPluginCookieStore *LLViewerMedia::sCookieStore = NULL;
   19.16  LLURL LLViewerMedia::sOpenIDURL;
   19.17  std::string LLViewerMedia::sOpenIDCookie;
   19.18  LLPluginClassMedia* LLViewerMedia::sSpareBrowserMediaSource = NULL;
   19.19 @@ -169,8 +167,6 @@
   19.20  static bool sAnyMediaShowing = false;
   19.21  static bool sAnyMediaPlaying = false;
   19.22  static boost::signals2::connection sTeleportFinishConnection;
   19.23 -static std::string sUpdatedCookies;
   19.24 -static const char *PLUGIN_COOKIE_FILE_NAME = "plugin_cookies.txt";
   19.25  
   19.26  //////////////////////////////////////////////////////////////////////////////////////////
   19.27  static void add_media_impl(LLViewerMediaImpl* media)
   19.28 @@ -610,12 +606,6 @@
   19.29  
   19.30  	sAnyMediaShowing = false;
   19.31  	sAnyMediaPlaying = false;
   19.32 -	sUpdatedCookies = getCookieStore()->getChangedCookies();
   19.33 -	if(!sUpdatedCookies.empty())
   19.34 -	{
   19.35 -		LL_DEBUGS() << "updated cookies will be sent to all loaded plugins: " << LL_ENDL;
   19.36 -		LL_DEBUGS() << sUpdatedCookies << LL_ENDL;
   19.37 -	}
   19.38  
   19.39  	impl_list::iterator iter = sViewerMediaImplList.begin();
   19.40  	impl_list::iterator end = sViewerMediaImplList.end();
   19.41 @@ -1059,64 +1049,6 @@
   19.42  			pimpl->mMediaSource->clear_cookies();
   19.43  		}
   19.44  	}
   19.45 -
   19.46 -	// Clear all cookies from the cookie store
   19.47 -	getCookieStore()->setAllCookies("");
   19.48 -
   19.49 -	// FIXME: this may not be sufficient, since the on-disk cookie file won't get written until some browser instance exits cleanly.
   19.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.
   19.51 -	// Until such time as we can centralize cookie storage, the following hack should cover these cases:
   19.52 -
   19.53 -	// HACK: Look for cookie files in all possible places and delete them.
   19.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)
   19.55 -
   19.56 -	// Places that cookie files can be:
   19.57 -	// <getOSUserAppDir>/browser_profile/cookies
   19.58 -	// <getOSUserAppDir>/first_last/browser_profile/cookies  (note that there may be any number of these!)
   19.59 -	// <getOSUserAppDir>/first_last/plugin_cookies.txt  (note that there may be any number of these!)
   19.60 -
   19.61 -	std::string base_dir = gDirUtilp->getOSUserAppDir() + gDirUtilp->getDirDelimiter();
   19.62 -	std::string target;
   19.63 -	std::string filename;
   19.64 -
   19.65 -	LL_DEBUGS() << "base dir = " << base_dir << LL_ENDL;
   19.66 -
   19.67 -	// The non-logged-in version is easy
   19.68 -	target = base_dir;
   19.69 -	target += "browser_profile";
   19.70 -	target += gDirUtilp->getDirDelimiter();
   19.71 -	target += "cookies";
   19.72 -	LL_DEBUGS() << "target = " << target << LL_ENDL;
   19.73 -	if(LLFile::isfile(target))
   19.74 -	{
   19.75 -		LLFile::remove(target);
   19.76 -	}
   19.77 -
   19.78 -	// the hard part: iterate over all user directories and delete the cookie file from each one
   19.79 -	LLDirIterator dir_iter(base_dir, "*_*");
   19.80 -	while (dir_iter.next(filename))
   19.81 -	{
   19.82 -		target = gDirUtilp->add(base_dir, filename);
   19.83 -		gDirUtilp->append(target, "browser_profile");
   19.84 -		gDirUtilp->append(target, "cookies");
   19.85 -		LL_DEBUGS() << "target = " << target << LL_ENDL;
   19.86 -		if(LLFile::isfile(target))
   19.87 -		{
   19.88 -			LLFile::remove(target);
   19.89 -		}
   19.90 -
   19.91 -		// Other accounts may have new-style cookie files too -- delete them as well
   19.92 -		target = gDirUtilp->add(base_dir, filename);
   19.93 -		gDirUtilp->append(target, PLUGIN_COOKIE_FILE_NAME);
   19.94 -		LL_DEBUGS() << "target = " << target << LL_ENDL;
   19.95 -		if(LLFile::isfile(target))
   19.96 -		{
   19.97 -			LLFile::remove(target);
   19.98 -		}
   19.99 -	}
  19.100 -
  19.101 -	// If we have an OpenID cookie, re-add it to the cookie store.
  19.102 -	setOpenIDCookie(std::string());
  19.103  }
  19.104  
  19.105  /////////////////////////////////////////////////////////////////////////////////////////
  19.106 @@ -1145,7 +1077,7 @@
  19.107  		LLViewerMediaImpl* pimpl = *iter;
  19.108  		if(pimpl->mMediaSource)
  19.109  		{
  19.110 -			pimpl->mMediaSource->enable_cookies(enabled);
  19.111 +			pimpl->mMediaSource->cookies_enabled(enabled);
  19.112  		}
  19.113  	}
  19.114  }
  19.115 @@ -1170,127 +1102,7 @@
  19.116  /////////////////////////////////////////////////////////////////////////////////////////
  19.117  // static
  19.118  /////////////////////////////////////////////////////////////////////////////////////////
  19.119 -// static
  19.120 -LLPluginCookieStore *LLViewerMedia::getCookieStore()
  19.121 -{
  19.122 -	if(sCookieStore == NULL)
  19.123 -	{
  19.124 -		sCookieStore = new LLPluginCookieStore;
  19.125 -	}
  19.126 -
  19.127 -	return sCookieStore;
  19.128 -}
  19.129 -
  19.130 -/////////////////////////////////////////////////////////////////////////////////////////
  19.131 -// static
  19.132 -void LLViewerMedia::loadCookieFile()
  19.133 -{
  19.134 -	// build filename for each user
  19.135 -	std::string resolved_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PLUGIN_COOKIE_FILE_NAME);
  19.136 -
  19.137 -	if (resolved_filename.empty())
  19.138 -	{
  19.139 -		LL_INFOS() << "can't get path to plugin cookie file - probably not logged in yet." << LL_ENDL;
  19.140 -		return;
  19.141 -	}
  19.142 -
  19.143 -	// open the file for reading
  19.144 -	llifstream file(resolved_filename.c_str());
  19.145 -	if (!file.is_open())
  19.146 -	{
  19.147 -		LL_WARNS() << "can't load plugin cookies from file \"" << PLUGIN_COOKIE_FILE_NAME << "\"" << LL_ENDL;
  19.148 -		return;
  19.149 -	}
  19.150 -
  19.151 -	getCookieStore()->readAllCookies(file, true);
  19.152 -
  19.153 -	file.close();
  19.154 -
  19.155 -	// send the clear_cookies message to all loaded plugins
  19.156 -	impl_list::iterator iter = sViewerMediaImplList.begin();
  19.157 -	impl_list::iterator end = sViewerMediaImplList.end();
  19.158 -	for (; iter != end; iter++)
  19.159 -	{
  19.160 -		LLViewerMediaImpl* pimpl = *iter;
  19.161 -		if(pimpl->mMediaSource)
  19.162 -		{
  19.163 -			pimpl->mMediaSource->clear_cookies();
  19.164 -		}
  19.165 -	}
  19.166 -
  19.167 -	// If we have an OpenID cookie, re-add it to the cookie store.
  19.168 -	setOpenIDCookie(std::string());
  19.169 -}
  19.170 -
  19.171 -
  19.172 -/////////////////////////////////////////////////////////////////////////////////////////
  19.173 -// static
  19.174 -void LLViewerMedia::saveCookieFile()
  19.175 -{
  19.176 -	// build filename for each user
  19.177 -	std::string resolved_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PLUGIN_COOKIE_FILE_NAME);
  19.178 -
  19.179 -	if (resolved_filename.empty())
  19.180 -	{
  19.181 -		LL_INFOS() << "can't get path to plugin cookie file - probably not logged in yet." << LL_ENDL;
  19.182 -		return;
  19.183 -	}
  19.184 -
  19.185 -	// open a file for writing
  19.186 -	llofstream file(resolved_filename.c_str());
  19.187 -	if (!file.is_open())
  19.188 -	{
  19.189 -		LL_WARNS() << "can't open plugin cookie file \"" << PLUGIN_COOKIE_FILE_NAME << "\" for writing" << LL_ENDL;
  19.190 -		return;
  19.191 -	}
  19.192 -
  19.193 -	getCookieStore()->writePersistentCookies(file);
  19.194 -
  19.195 -	file.close();
  19.196 -}
  19.197 -
  19.198 -/////////////////////////////////////////////////////////////////////////////////////////
  19.199 -// static
  19.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)
  19.201 -{
  19.202 -	std::stringstream cookie;
  19.203 -
  19.204 -	cookie << name << "=" << LLPluginCookieStore::quoteString(value);
  19.205 -
  19.206 -	if(expires.notNull())
  19.207 -	{
  19.208 -		cookie << "; expires=" << expires.asRFC1123();
  19.209 -	}
  19.210 -
  19.211 -	cookie << "; domain=" << domain;
  19.212 -
  19.213 -	cookie << "; path=" << path;
  19.214 -
  19.215 -	if(secure)
  19.216 -	{
  19.217 -		cookie << "; secure";
  19.218 -	}
  19.219 -
  19.220 -	getCookieStore()->setCookies(cookie.str());
  19.221 -}
  19.222 -
  19.223 -/////////////////////////////////////////////////////////////////////////////////////////
  19.224 -// static
  19.225 -void LLViewerMedia::addSessionCookie(const std::string &name, const std::string &value, const std::string &domain, const std::string &path, bool secure)
  19.226 -{
  19.227 -	// A session cookie just has a NULL date.
  19.228 -	addCookie(name, value, domain, LLDate(), path, secure);
  19.229 -}
  19.230 -
  19.231 -/////////////////////////////////////////////////////////////////////////////////////////
  19.232 -// static
  19.233 -void LLViewerMedia::removeCookie(const std::string &name, const std::string &domain, const std::string &path )
  19.234 -{
  19.235 -	// To remove a cookie, add one with the same name, domain, and path that expires in the past.
  19.236 -
  19.237 -	addCookie(name, "", domain, LLDate(LLDate::now().secondsSinceEpoch() - 1.0), path);
  19.238 -}
  19.239 -
  19.240 +//// static
  19.241  
  19.242  LLSD LLViewerMedia::getHeaders()
  19.243  {
  19.244 @@ -1395,8 +1207,6 @@
  19.245          hostEnd = authority.size();
  19.246      }
  19.247  
  19.248 -    getCookieStore()->setCookiesFromHost(sOpenIDCookie, authority.substr(hostStart, hostEnd - hostStart));
  19.249 -
  19.250  	if (url.length())
  19.251  	{
  19.252  		LLMediaCtrl* media_instance = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("destination_guide_contents");
  19.253 @@ -1434,7 +1244,6 @@
  19.254      httpHeaders->append(HTTP_OUT_HEADER_COOKIE, sOpenIDCookie);
  19.255      httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, getCurrentUserAgent());
  19.256  
  19.257 -
  19.258      LL_DEBUGS("MediaAuth") << "Requesting " << url << LL_ENDL;
  19.259      LL_DEBUGS("MediaAuth") << "sOpenIDCookie = [" << sOpenIDCookie << "]" << LL_ENDL;
  19.260      
  19.261 @@ -1459,13 +1268,9 @@
  19.262      const std::string& cookie = resultHeaders[HTTP_IN_HEADER_SET_COOKIE].asStringRef();
  19.263      LL_DEBUGS("MediaAuth") << "cookie = " << cookie << LL_ENDL;
  19.264  
  19.265 -    // *TODO: What about bad status codes?  Does this destroy previous cookies?
  19.266 -    LLViewerMedia::getCookieStore()->setCookiesFromHost(cookie, hostAuth);
  19.267 -
  19.268      // Set cookie for snapshot publishing.
  19.269      std::string authCookie = cookie.substr(0, cookie.find(";")); // strip path
  19.270      LLWebProfile::setAuthCookie(authCookie);
  19.271 -
  19.272  }
  19.273  
  19.274  /////////////////////////////////////////////////////////////////////////////////////////
  19.275 @@ -1660,12 +1465,6 @@
  19.276  		delete sSpareBrowserMediaSource;
  19.277  		sSpareBrowserMediaSource = NULL;
  19.278  	}
  19.279 -
  19.280 -	if (sCookieStore != NULL)
  19.281 -	{
  19.282 -		delete sCookieStore;
  19.283 -		sCookieStore = NULL;
  19.284 -	}
  19.285  }
  19.286  
  19.287  //////////////////////////////////////////////////////////////////////////////////////////
  19.288 @@ -1898,6 +1697,8 @@
  19.289  		std::string user_data_path_cookies = gDirUtilp->getOSUserAppDir();
  19.290  		user_data_path_cookies += gDirUtilp->getDirDelimiter();
  19.291  
  19.292 +		std::string user_data_path_cef_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "cef_log.txt");
  19.293 +
  19.294  		// Fix for EXT-5960 - make browser profile specific to user (cache, cookies etc.)
  19.295  		// If the linden username returned is blank, that can only mean we are
  19.296  		// at the login page displaying login Web page or Web browser test via Develop menu.
  19.297 @@ -1906,7 +1707,6 @@
  19.298  		std::string linden_user_dir = gDirUtilp->getLindenUserDir();
  19.299  		if ( ! linden_user_dir.empty() )
  19.300  		{
  19.301 -			// gDirUtilp->getLindenUserDir() is whole path, not just Linden name
  19.302  			user_data_path_cookies = linden_user_dir;
  19.303  			user_data_path_cookies += gDirUtilp->getDirDelimiter();
  19.304  		};
  19.305 @@ -1927,13 +1727,13 @@
  19.306  		{
  19.307  			media_source = new LLPluginClassMedia(owner);
  19.308  			media_source->setSize(default_width, default_height);
  19.309 -			media_source->setUserDataPath(user_data_path_cache, user_data_path_cookies);
  19.310 +			media_source->setUserDataPath(user_data_path_cache, user_data_path_cookies, user_data_path_cef_log);
  19.311  			media_source->setLanguageCode(LLUI::getLanguage());
  19.312  			media_source->setZoomFactor(zoom_factor);
  19.313  
  19.314  			// collect 'cookies enabled' setting from prefs and send to embedded browser
  19.315  			bool cookies_enabled = gSavedSettings.getBOOL( "CookiesEnabled" );
  19.316 -			media_source->enable_cookies( cookies_enabled || clean_browser);
  19.317 +			media_source->cookies_enabled( cookies_enabled || clean_browser);
  19.318  
  19.319  			// collect 'plugins enabled' setting from prefs and send to embedded browser
  19.320  			bool plugins_enabled = gSavedSettings.getBOOL( "BrowserPluginsEnabled" );
  19.321 @@ -2040,17 +1840,6 @@
  19.322  			media_source->clear_cache();
  19.323  		}
  19.324  
  19.325 -		// TODO: Only send cookies to plugins that need them
  19.326 -		//  Ideally, the plugin should tell us whether it handles cookies or not -- either via the init response or through a separate message.
  19.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,
  19.328 -		//  which could cause odd race conditions.
  19.329 -		std::string all_cookies = LLViewerMedia::getCookieStore()->getAllCookies();
  19.330 -		LL_DEBUGS() << "setting cookies: " << all_cookies << LL_ENDL;
  19.331 -		if(!all_cookies.empty())
  19.332 -		{
  19.333 -			media_source->set_cookies(all_cookies);
  19.334 -		}
  19.335 -
  19.336  		mMediaSource = media_source;
  19.337  		mMediaSource->setDeleteOK(false) ;
  19.338  		updateVolume();
  19.339 @@ -2992,14 +2781,10 @@
  19.340  		updateVolume();
  19.341  
  19.342  		// TODO: this is updated every frame - is this bad?
  19.343 -		updateJavascriptObject();
  19.344 -
  19.345 -		// If we didn't just create the impl, it may need to get cookie updates.
  19.346 -		if(!sUpdatedCookies.empty())
  19.347 -		{
  19.348 -			// TODO: Only send cookies to plugins that need them
  19.349 -			mMediaSource->set_cookies(sUpdatedCookies);
  19.350 -		}
  19.351 +		// Removing this as part of the post viewer64 media update
  19.352 +		// Removed as not implemented in CEF embedded browser
  19.353 +		// See MAINT-8194 for a more fuller description
  19.354 +		// updateJavascriptObject();
  19.355  	}
  19.356  
  19.357  
  19.358 @@ -3489,22 +3274,40 @@
  19.359  
  19.360  		case LLViewerMediaObserver::MEDIA_EVENT_PICK_FILE_REQUEST:
  19.361  		{
  19.362 -			// Display a file picker
  19.363 -			std::string response;
  19.364 -
  19.365  			LLFilePicker& picker = LLFilePicker::instance();
  19.366 -			if (!picker.getOpenFile(LLFilePicker::FFLOAD_ALL))
  19.367 +			std::vector<std::string> responses;
  19.368 +
  19.369 +			bool pick_multiple_files = plugin->getIsMultipleFilePick();
  19.370 +			if (pick_multiple_files == false)
  19.371  			{
  19.372 -				// The user didn't pick a file -- the empty response string will indicate this.
  19.373 +				picker.getOpenFile(LLFilePicker::FFLOAD_ALL);
  19.374 +
  19.375 +				std::string filename = picker.getFirstFile();
  19.376 +				responses.push_back(filename);
  19.377  			}
  19.378 -
  19.379 -			response = picker.getFirstFile();
  19.380 -
  19.381 -			plugin->sendPickFileResponse(response);
  19.382 +			else
  19.383 +			{
  19.384 +				if (picker.getMultipleOpenFiles())
  19.385 +				{
  19.386 +					std::string filename = picker.getFirstFile();
  19.387 +
  19.388 +					responses.push_back(filename);
  19.389 +
  19.390 +					while (!filename.empty())
  19.391 +					{
  19.392 +						filename = picker.getNextFile();
  19.393 +
  19.394 +						if (!filename.empty())
  19.395 +						{
  19.396 +							responses.push_back(filename);
  19.397 +						}
  19.398 +					}
  19.399 +				}
  19.400 +			}
  19.401 +			plugin->sendPickFileResponse(responses);
  19.402  		}
  19.403  		break;
  19.404  
  19.405 -
  19.406  		case LLViewerMediaObserver::MEDIA_EVENT_AUTH_REQUEST:
  19.407  		{
  19.408  			LLNotification::Params auth_request_params;
  19.409 @@ -3574,13 +3377,6 @@
  19.410  
  19.411  ////////////////////////////////////////////////////////////////////////////////
  19.412  // virtual
  19.413 -void LLViewerMediaImpl::handleCookieSet(LLPluginClassMedia* self, const std::string &cookie)
  19.414 -{
  19.415 -	LLViewerMedia::getCookieStore()->setCookies(cookie);
  19.416 -}
  19.417 -
  19.418 -////////////////////////////////////////////////////////////////////////////////
  19.419 -// virtual
  19.420  void
  19.421  LLViewerMediaImpl::cut()
  19.422  {
    20.1 --- a/indra/newview/llviewermedia.h	Fri Apr 06 14:15:11 2018 +0000
    20.2 +++ b/indra/newview/llviewermedia.h	Thu Apr 12 21:22:22 2018 +0300
    20.3 @@ -50,7 +50,6 @@
    20.4  class LLMediaEntry;
    20.5  class LLVOVolume;
    20.6  class LLMimeDiscoveryResponder;
    20.7 -class LLPluginCookieStore;
    20.8  
    20.9  typedef LLPointer<LLViewerMediaImpl> viewer_media_t;
   20.10  ///////////////////////////////////////////////////////////////////////////////
   20.11 @@ -149,13 +148,6 @@
   20.12  	// Set the proxy config for all loaded plugins
   20.13  	static void setProxyConfig(bool enable, const std::string &host, int port);
   20.14  	
   20.15 -	static LLPluginCookieStore *getCookieStore();
   20.16 -	static void loadCookieFile();
   20.17 -	static void saveCookieFile();
   20.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 );
   20.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 );
   20.20 -	static void removeCookie(const std::string &name, const std::string &domain, const std::string &path = std::string("/") );
   20.21 -
   20.22  	static void openIDSetup(const std::string &openid_url, const std::string &openid_token);
   20.23  	static void openIDCookieResponse(const std::string& url, const std::string &cookie);
   20.24  	
   20.25 @@ -178,7 +170,6 @@
   20.26      static void openIDSetupCoro(std::string openidUrl, std::string openidToken);
   20.27      static void getOpenIDCookieCoro(std::string url);
   20.28  
   20.29 -	static LLPluginCookieStore *sCookieStore;
   20.30  	static LLURL sOpenIDURL;
   20.31  	static std::string sOpenIDCookie;
   20.32  	static LLPluginClassMedia* sSpareBrowserMediaSource;
   20.33 @@ -337,7 +328,6 @@
   20.34  
   20.35  	// Inherited from LLPluginClassMediaOwner
   20.36  	/*virtual*/ void handleMediaEvent(LLPluginClassMedia* plugin, LLPluginClassMediaOwner::EMediaEvent);
   20.37 -	/*virtual*/ void handleCookieSet(LLPluginClassMedia* self, const std::string &cookie);
   20.38  
   20.39  	// LLEditMenuHandler overrides
   20.40  	/*virtual*/ void	cut();
    21.1 --- a/indra/newview/llwebprofile.cpp	Fri Apr 06 14:15:11 2018 +0000
    21.2 +++ b/indra/newview/llwebprofile.cpp	Thu Apr 12 21:22:22 2018 +0300
    21.3 @@ -31,7 +31,6 @@
    21.4  // libs
    21.5  #include "llbufferstream.h"
    21.6  #include "llimagepng.h"
    21.7 -#include "llplugincookiestore.h"
    21.8  
    21.9  #include "llsdserialize.h"
   21.10  
    22.1 --- a/indra/newview/skins/default/xui/en/floater_about.xml	Fri Apr 06 14:15:11 2018 +0000
    22.2 +++ b/indra/newview/skins/default/xui/en/floater_about.xml	Thu Apr 12 21:22:22 2018 +0300
    22.3 @@ -8,14 +8,14 @@
    22.4   help_topic="floater_about"
    22.5   save_rect="true"
    22.6   title="ABOUT [CAPITALIZED_APP_NAME]"
    22.7 - width="470">
    22.8 + width="500">
    22.9    
   22.10    <tab_container
   22.11      follows="all" 
   22.12      top="25"
   22.13      left="10"
   22.14      height="405" 
   22.15 -    width="450" 
   22.16 +    width="480" 
   22.17      name="about_tab"
   22.18      tab_position="top">
   22.19      <panel
   22.20 @@ -33,7 +33,7 @@
   22.21         max_length="65536"
   22.22         name="support_editor"
   22.23         top="5"
   22.24 -       width="435"
   22.25 +       width="465"
   22.26         word_wrap="true" />
   22.27        <button
   22.28          follows="left|top" 
   22.29 @@ -56,7 +56,7 @@
   22.30            left="5"
   22.31            name="linden_intro"
   22.32            top="10"
   22.33 -          width="435"
   22.34 +          width="465"
   22.35            wrap="true">
   22.36  Second Life is brought to you by the Lindens, 
   22.37  with open source contributions from:
   22.38 @@ -71,7 +71,7 @@
   22.39         max_length="65536"
   22.40         name="contrib_names"
   22.41         top_pad="10"
   22.42 -       width="435"
   22.43 +       width="465"
   22.44         word_wrap="true">
   22.45  Dummy Name replaced at run time
   22.46        </text_editor>
   22.47 @@ -91,7 +91,7 @@
   22.48         max_length="65536"
   22.49         name="licenses_editor"
   22.50         top="5"
   22.51 -       width="435"
   22.52 +       width="465"
   22.53         word_wrap="true">
   22.54          3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion
   22.55          APR Copyright (C) 2011 The Apache Software Foundation
    23.1 --- a/indra/newview/skins/default/xui/en/floater_web_content.xml	Fri Apr 06 14:15:11 2018 +0000
    23.2 +++ b/indra/newview/skins/default/xui/en/floater_web_content.xml	Thu Apr 12 21:22:22 2018 +0300
    23.3 @@ -178,108 +178,7 @@
    23.4          width="22">
    23.5          <button.commit_callback
    23.6            function="WebContent.TestURL"
    23.7 -          parameter="https://callum-linden.s3.amazonaws.com/ceftests.html"/>
    23.8 -      </button>
    23.9 -
   23.10 -      <button
   23.11 -        image_overlay="Video_URL_Off"
   23.12 -            image_disabled="PushButton_Disabled"
   23.13 -            image_disabled_selected="PushButton_Disabled"
   23.14 -            image_selected="PushButton_Selected"
   23.15 -            image_unselected="PushButton_Off"
   23.16 -        chrome="true"
   23.17 -        tool_tip="MPEG4 Video Test"
   23.18 -        enabled="true"
   23.19 -        follows="left|top"
   23.20 -        height="22"
   23.21 -        layout="topleft"
   23.22 -        left="27"
   23.23 -        name="VLC Plugin Test"
   23.24 -        top="0"
   23.25 -        width="22">
   23.26 -        <button.commit_callback
   23.27 -          function="WebContent.TestURL"
   23.28 -          parameter="https://callum-linden.s3.amazonaws.com/sample_media/ss.mp4"/>
   23.29 -      </button>
   23.30 -      <button
   23.31 -        image_overlay="Video_URL_Off"
   23.32 -            image_disabled="PushButton_Disabled"
   23.33 -            image_disabled_selected="PushButton_Disabled"
   23.34 -            image_selected="PushButton_Selected"
   23.35 -            image_unselected="PushButton_Off"
   23.36 -        chrome="true"
   23.37 -        tool_tip="MKV Video Test"
   23.38 -        enabled="true"
   23.39 -        follows="left|top"
   23.40 -        height="22"
   23.41 -        layout="topleft"
   23.42 -        left="51"
   23.43 -        name="VLC Plugin Test"
   23.44 -        top="0"
   23.45 -        width="22">
   23.46 -        <button.commit_callback
   23.47 -          function="WebContent.TestURL"
   23.48 -          parameter="https://callum-linden.s3.amazonaws.com/sample_media/jellyfish.mkv"/>
   23.49 -      </button>
   23.50 -      <button
   23.51 -        image_overlay="Video_URL_Off"
   23.52 -            image_disabled="PushButton_Disabled"
   23.53 -            image_disabled_selected="PushButton_Disabled"
   23.54 -            image_selected="PushButton_Selected"
   23.55 -            image_unselected="PushButton_Off"
   23.56 -        chrome="true"
   23.57 -        tool_tip="WebM Video Test"
   23.58 -        enabled="true"
   23.59 -        follows="left|top"
   23.60 -        height="22"
   23.61 -        layout="topleft"
   23.62 -        left="75"
   23.63 -        name="VLC Plugin Test"
   23.64 -        top="0"
   23.65 -        width="22">
   23.66 -        <button.commit_callback
   23.67 -          function="WebContent.TestURL"
   23.68 -          parameter="https://callum-linden.s3.amazonaws.com/sample_media/jumprope.webm"/>
   23.69 -      </button>
   23.70 -      <button
   23.71 -        image_overlay="Video_URL_Off"
   23.72 -            image_disabled="PushButton_Disabled"
   23.73 -            image_disabled_selected="PushButton_Disabled"
   23.74 -            image_selected="PushButton_Selected"
   23.75 -            image_unselected="PushButton_Off"
   23.76 -        chrome="true"
   23.77 -        tool_tip="MP3 audio Test"
   23.78 -        enabled="true"
   23.79 -        follows="left|top"
   23.80 -        height="22"
   23.81 -        layout="topleft"
   23.82 -        left="99"
   23.83 -        name="VLC Plugin Test"
   23.84 -        top="0"
   23.85 -        width="22">
   23.86 -        <button.commit_callback
   23.87 -          function="WebContent.TestURL"
   23.88 -          parameter="https://callum-linden.s3.amazonaws.com/alegria.mp3"/>
   23.89 -      </button>
   23.90 -      <button
   23.91 -        image_overlay="Video_URL_Off"
   23.92 -            image_disabled="PushButton_Disabled"
   23.93 -            image_disabled_selected="PushButton_Disabled"
   23.94 -            image_selected="PushButton_Selected"
   23.95 -            image_unselected="PushButton_Off"
   23.96 -        chrome="true"
   23.97 -        tool_tip="FLV Test"
   23.98 -        enabled="true"
   23.99 -        follows="left|top"
  23.100 -        height="22"
  23.101 -        layout="topleft"
  23.102 -        left="123"
  23.103 -        name="VLC Plugin Test"
  23.104 -        top="0"
  23.105 -        width="22">
  23.106 -        <button.commit_callback
  23.107 -          function="WebContent.TestURL"
  23.108 -          parameter="https://callum-linden.s3.amazonaws.com/sample_media/vandal.flv"/>
  23.109 +          parameter="https://sl-viewer-media-system.s3.amazonaws.com/index.html"/>
  23.110        </button>
  23.111      </layout_panel>
  23.112      <layout_panel
    24.1 --- a/indra/newview/skins/default/xui/en/menu_login.xml	Fri Apr 06 14:15:11 2018 +0000
    24.2 +++ b/indra/newview/skins/default/xui/en/menu_login.xml	Thu Apr 12 21:22:22 2018 +0300
    24.3 @@ -245,7 +245,7 @@
    24.4         name="Media Browser">
    24.5          <menu_item_call.on_click
    24.6           function="Advanced.WebContentTest"
    24.7 -         parameter="http://google.com"/>
    24.8 +         parameter="http://duckduckgo.com"/>
    24.9        </menu_item_call>
   24.10        <menu
   24.11         create_jump_keys="true"
    25.1 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml	Fri Apr 06 14:15:11 2018 +0000
    25.2 +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml	Thu Apr 12 21:22:22 2018 +0300
    25.3 @@ -3163,7 +3163,7 @@
    25.4             shortcut="control|alt|shift|Z">
    25.5              <menu_item_call.on_click
    25.6               function="Advanced.WebContentTest"
    25.7 -             parameter="http://google.com"/>
    25.8 +             parameter="http://duckduckgo.com"/>
    25.9            </menu_item_call>
   25.10            <menu_item_call
   25.11             label="FB Connect Test"
    26.1 --- a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml	Fri Apr 06 14:15:11 2018 +0000
    26.2 +++ b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml	Thu Apr 12 21:22:22 2018 +0300
    26.3 @@ -19,7 +19,7 @@
    26.4        follows="left|top"
    26.5        height="23"
    26.6        label="Clear History"
    26.7 -      tool_tip="Clear login image, last location, teleport history, web, and texture cache"
    26.8 +      tool_tip="Clear login image, last location, teleport history, web and texture cache"
    26.9        layout="topleft"
   26.10        left="30"
   26.11        name="clear_cache"
    27.1 --- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml	Fri Apr 06 14:15:11 2018 +0000
    27.2 +++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml	Thu Apr 12 21:22:22 2018 +0300
    27.3 @@ -106,38 +106,6 @@
    27.4           width="300">
    27.5      Web:
    27.6    </text>
    27.7 - <!-- <radio_group
    27.8 -   control_name="UseExternalBrowser"
    27.9 -   draw_border="false"
   27.10 -   follows="top|left"
   27.11 -   height="40"
   27.12 -   layout="topleft"
   27.13 -   left_delta="50"
   27.14 -   name="use_external_browser"
   27.15 -   top_pad="-2"
   27.16 -   width="480">
   27.17 -    <radio_item
   27.18 -      height="20"
   27.19 -      label="Use my browser (IE, Firefox, Safari)"
   27.20 -      layout="topleft"
   27.21 -      left_delta="0"
   27.22 -      name="external"
   27.23 -      value="true"
   27.24 -      top="0"
   27.25 -      tool_tip="Use the default system web browser for help, web links, etc. Not recommended if running full screen."
   27.26 -      width="480" />
   27.27 -    <radio_item
   27.28 -      height="20"
   27.29 -      label="Use built-in browser"
   27.30 -      layout="topleft"
   27.31 -      left="0"
   27.32 -      name="internal"
   27.33 -      value=""
   27.34 -      tool_tip="Use the built-in web browser for help, web links, etc. This browser opens as a new window inside [APP_NAME]."
   27.35 -      top_delta="20"
   27.36 -      width="480" />
   27.37 -  </radio_group> -->
   27.38 -
   27.39    <radio_group
   27.40     control_name="PreferredBrowserBehavior"
   27.41     follows="left|top"
   27.42 @@ -149,7 +117,7 @@
   27.43     width="480">
   27.44      <radio_item
   27.45        height="20"
   27.46 -      label="Use my browser (Chrome, Firefox, IE) for all links"
   27.47 +      label="Use the default system browser for all links"
   27.48        layout="topleft"
   27.49        left="0"
   27.50        name="internal"
   27.51 @@ -159,17 +127,17 @@
   27.52        width="480" />
   27.53      <radio_item
   27.54        height="20"
   27.55 -      label="Use built-in browser for Second Life links only"
   27.56 +      label="Use the built-in browser for Second Life links only"
   27.57        layout="topleft"
   27.58        left_delta="0"
   27.59        name="external"
   27.60        value="1"      
   27.61 -      tool_tip="Use the default system web browser for help, web links, etc. Builtin browser will be used only for LindenLab/SecondLife links."
   27.62 +      tool_tip="Use the default system web browser for help, web links, etc. The built-in browser will be used only for LindenLab/Second Life links."
   27.63        top_delta="20"
   27.64        width="480" />
   27.65      <radio_item
   27.66        height="20"
   27.67 -      label="Use built-in browser for all links"
   27.68 +      label="Use the built-in browser for all links"
   27.69        layout="topleft"
   27.70        left="0"
   27.71        name="external_all"
   27.72 @@ -193,22 +161,6 @@
   27.73      radio_style="false"
   27.74      width="400"
   27.75      top_pad="5"/>
   27.76 -
   27.77 -  <check_box
   27.78 -   top_delta="4"
   27.79 -   enabled="true"
   27.80 -   follows="left|top"
   27.81 -   height="14"
   27.82 -   initial_value="true"
   27.83 -   control_name="CookiesEnabled"
   27.84 -   label="Accept cookies"
   27.85 -   left_delta="0"
   27.86 -   mouse_opaque="true" 
   27.87 -   name="cookies_enabled"
   27.88 -   radio_style="false"
   27.89 -   width="400"
   27.90 -   top_pad="5"/>
   27.91 -  
   27.92    <check_box
   27.93      top_delta="4"
   27.94      enabled="true"

mercurial