diff options
Diffstat (limited to 'indra')
22 files changed, 208 insertions, 1543 deletions
| diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt index 129efeb529..5cc129a267 100644 --- a/indra/llplugin/CMakeLists.txt +++ b/indra/llplugin/CMakeLists.txt @@ -29,7 +29,6 @@ include_directories(SYSTEM  set(llplugin_SOURCE_FILES      llpluginclassmedia.cpp -    llplugincookiestore.cpp      llplugininstance.cpp      llpluginmessage.cpp      llpluginmessagepipe.cpp @@ -43,7 +42,6 @@ set(llplugin_HEADER_FILES      llpluginclassmedia.h      llpluginclassmediaowner.h -    llplugincookiestore.h      llplugininstance.h      llpluginmessage.h      llpluginmessageclasses.h @@ -70,20 +68,3 @@ add_library (llplugin ${llplugin_SOURCE_FILES})  add_subdirectory(slplugin) -# Add tests -if (LL_TESTS) -    include(LLAddBuildTest) -    # UNIT TESTS -    SET(llplugin_TEST_SOURCE_FILES -      llplugincookiestore.cpp -      ) - -    # llplugincookiestore has a dependency on curl, so we need to link the curl library into the test. -    set_source_files_properties( -      llplugincookiestore.cpp -      PROPERTIES -        LL_TEST_ADDITIONAL_LIBRARIES "${CURL_LIBRARIES};${NGHTTP2_LIBRARIES}" -      ) - -    LL_ADD_PROJECT_UNIT_TESTS(llplugin "${llplugin_TEST_SOURCE_FILES}") -endif (LL_TESTS) diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index 680017204c..78eb6e75bb 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -31,6 +31,9 @@  #include "llpluginclassmedia.h"  #include "llpluginmessageclasses.h" +#include "llcontrol.h" + +extern LLControlGroup gSavedSettings;      static int LOW_PRIORITY_TEXTURE_SIZE_DEFAULT = 256; @@ -792,15 +795,22 @@ F64 LLPluginClassMedia::getCPUUsage()  	return result;  } -void LLPluginClassMedia::sendPickFileResponse(const std::string &file) +void LLPluginClassMedia::sendPickFileResponse(const std::vector<std::string> files)  {  	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file_response"); -	message.setValue("file", file);  	if(mPlugin && mPlugin->isBlocked())  	{  		// If the plugin sent a blocking pick-file request, the response should unblock it.  		message.setValueBoolean("blocking_response", true);  	} + +	LLSD file_list = LLSD::emptyArray(); +	for (std::vector<std::string>::const_iterator in_iter = files.begin(); in_iter != files.end(); ++in_iter) +	{ +		file_list.append(LLSD::String(*in_iter)); +	} +	message.setValueLLSD("file_list", file_list); +  	sendMessage(message);  } @@ -836,11 +846,17 @@ void LLPluginClassMedia::paste()  	sendMessage(message);  } -void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path_cache, const std::string &user_data_path_cookies) +void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path_cache, +										 const std::string &user_data_path_cookies, +										 const std::string &user_data_path_cef_log)  {  	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "set_user_data_path");  	message.setValue("cache_path", user_data_path_cache);  	message.setValue("cookies_path", user_data_path_cookies); +	message.setValue("cef_log_file", user_data_path_cef_log); + +	bool cef_verbose_log = gSavedSettings.getBOOL("CefVerboseLog"); +	message.setValueBoolean("cef_verbose_log", cef_verbose_log);  	sendMessage(message);  } @@ -1090,6 +1106,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)  		}  		else if(message_name == "pick_file")  		{ +			mIsMultipleFilePick = message.getValueBoolean("multiple_files");  			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PICK_FILE_REQUEST);  		}  		else if(message_name == "auth_request") @@ -1151,7 +1168,12 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)  		{  			mClickURL = message.getValue("uri");  			mClickTarget = message.getValue("target"); -			mClickUUID = message.getValue("uuid"); + +			// need a link to have a UUID that identifies it to a system further +			// upstream - plugin could make it but we have access to LLUUID here +			// so why don't we use it +			mClickUUID = LLUUID::generateNewID().asString(); +  			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_HREF);  		}  		else if(message_name == "click_nofollow") @@ -1166,13 +1188,6 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)  			mStatusCode = message.getValueS32("status_code");  			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAVIGATE_ERROR_PAGE);  		} -		else if(message_name == "cookie_set") -		{ -			if(mOwner) -			{ -				mOwner->handleCookieSet(this, message.getValue("cookie")); -			} -		}  		else if(message_name == "close_request")  		{  			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLOSE_REQUEST); @@ -1287,16 +1302,9 @@ void LLPluginClassMedia::clear_cookies()  	sendMessage(message);  } -void LLPluginClassMedia::set_cookies(const std::string &cookies) -{ -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_cookies"); -	message.setValue("cookies", cookies); -	sendMessage(message); -} - -void LLPluginClassMedia::enable_cookies(bool enable) +void LLPluginClassMedia::cookies_enabled(bool enable)  { -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "enable_cookies"); +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "cookies_enabled");  	message.setValueBoolean("enable", enable);  	sendMessage(message);  } diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h index 3b0739d044..3b3075c6bd 100644 --- a/indra/llplugin/llpluginclassmedia.h +++ b/indra/llplugin/llpluginclassmedia.h @@ -176,7 +176,7 @@ public:  	F64 getCPUUsage(); -	void sendPickFileResponse(const std::string &file); +	void sendPickFileResponse(const std::vector<std::string> files);  	void sendAuthResponse(bool ok, const std::string &username, const std::string &password); @@ -195,7 +195,7 @@ public:  	bool	canPaste() const { return mCanPaste; };  	// These can be called before init(), and they will be queued and sent before the media init message. -	void	setUserDataPath(const std::string &user_data_path_cache, const std::string &user_data_path_cookies); +	void	setUserDataPath(const std::string &user_data_path_cache, const std::string &user_data_path_cookies, const std::string &user_data_path_cef_log);  	void	setLanguageCode(const std::string &language_code);  	void	setPluginsEnabled(const bool enabled);  	void	setJavascriptEnabled(const bool enabled); @@ -210,7 +210,7 @@ public:  	void clear_cache();  	void clear_cookies();  	void set_cookies(const std::string &cookies); -	void enable_cookies(bool enable); +	void cookies_enabled(bool enable);  	void proxy_setup(bool enable, const std::string &host = LLStringUtil::null, int port = 0);  	void browse_stop();  	void browse_reload(bool ignore_cache = false); @@ -277,6 +277,9 @@ public:  	std::string	getAuthURL() const { return mAuthURL; };  	std::string	getAuthRealm() const { return mAuthRealm; }; +	// These are valid during MEDIA_EVENT_PICK_FILE_REQUEST +	bool getIsMultipleFilePick() const { return mIsMultipleFilePick; } +  	// These are valid during MEDIA_EVENT_LINK_HOVERED  	std::string	getHoverText() const { return mHoverText; };  	std::string	getHoverLink() const { return mHoverLink; }; @@ -435,6 +438,7 @@ protected:  	std::string		mHoverText;  	std::string		mHoverLink;  	std::string     mFileDownloadFilename; +	bool			mIsMultipleFilePick;  	/////////////////////////////////////////  	// media_time class diff --git a/indra/llplugin/llpluginclassmediaowner.h b/indra/llplugin/llpluginclassmediaowner.h index 391c23d883..89f55eaf71 100644 --- a/indra/llplugin/llpluginclassmediaowner.h +++ b/indra/llplugin/llpluginclassmediaowner.h @@ -1,4 +1,4 @@ -/**  +/**   * @file llpluginclassmediaowner.h   * @brief LLPluginClassMedia handles interaction with a plugin which knows about the "media" message class.   * @@ -6,21 +6,21 @@   * $LicenseInfo:firstyear=2008&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library is distributed in the hope that it will be useful,   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   * @endcond @@ -34,18 +34,17 @@  #include <queue>  class LLPluginClassMedia; -class LLPluginCookieStore;  class LLPluginClassMediaOwner  {  public:  	typedef enum  	{ -		MEDIA_EVENT_CONTENT_UPDATED,		// contents/dirty rect have updated  +		MEDIA_EVENT_CONTENT_UPDATED,		// contents/dirty rect have updated  		MEDIA_EVENT_TIME_DURATION_UPDATED,	// current time and/or duration have updated  		MEDIA_EVENT_SIZE_CHANGED,			// media size has changed  		MEDIA_EVENT_CURSOR_CHANGED,			// plugin has requested a cursor change -		 +  		MEDIA_EVENT_NAVIGATE_BEGIN,			// browser has begun navigation  		MEDIA_EVENT_NAVIGATE_COMPLETE,		// browser has finished navigation  		MEDIA_EVENT_PROGRESS_UPDATED,		// browser has updated loading progress @@ -58,8 +57,8 @@ public:  		MEDIA_EVENT_CLOSE_REQUEST,			// The plugin requested its window be closed (currently hooked up to javascript window.close in webkit)  		MEDIA_EVENT_PICK_FILE_REQUEST,		// The plugin wants the user to pick a file  		MEDIA_EVENT_GEOMETRY_CHANGE,		// The plugin requested its window geometry be changed (per the javascript window interface) -	 -		MEDIA_EVENT_PLUGIN_FAILED_LAUNCH,	// The plugin failed to launch  + +		MEDIA_EVENT_PLUGIN_FAILED_LAUNCH,	// The plugin failed to launch  		MEDIA_EVENT_PLUGIN_FAILED,			// The plugin died unexpectedly  		MEDIA_EVENT_AUTH_REQUEST,			// The plugin wants to display an auth dialog @@ -69,9 +68,9 @@ public:  		MEDIA_EVENT_DEBUG_MESSAGE,			// plugin sending back debug information for host to process  		MEDIA_EVENT_LINK_HOVERED			// Got a "link hovered" event from the plugin -		 +  	} EMediaEvent; -	 +  	typedef enum  	{  		MEDIA_NONE,			// Uninitialized -- no useful state @@ -81,12 +80,11 @@ public:  		MEDIA_PLAYING,		// playing (only for time-based media)  		MEDIA_PAUSED,		// paused (only for time-based media)  		MEDIA_DONE			// finished playing (only for time-based media) -	 +  	} EMediaStatus; -	 +  	virtual ~LLPluginClassMediaOwner() {};  	virtual void handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent /*event*/) {}; -	virtual void handleCookieSet(LLPluginClassMedia* /*self*/, const std::string &/*cookie*/) {};  };  #endif // LL_LLPLUGINCLASSMEDIAOWNER_H diff --git a/indra/llplugin/llplugincookiestore.cpp b/indra/llplugin/llplugincookiestore.cpp deleted file mode 100644 index a5d717389d..0000000000 --- a/indra/llplugin/llplugincookiestore.cpp +++ /dev/null @@ -1,689 +0,0 @@ -/**  - * @file llplugincookiestore.cpp - * @brief LLPluginCookieStore provides central storage for http cookies used by plugins - * - * @cond - * $LicenseInfo:firstyear=2010&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - * @endcond - */ - -#include "linden_common.h" -#include "llstl.h" -#include "indra_constants.h" - -#include "llplugincookiestore.h" -#include <iostream> - -// for curl_getdate() (apparently parsing RFC 1123 dates is hard) -#include <curl/curl.h> - -LLPluginCookieStore::LLPluginCookieStore(): -	mHasChangedCookies(false) -{ -} - - -LLPluginCookieStore::~LLPluginCookieStore() -{ -	clearCookies(); -} - - -LLPluginCookieStore::Cookie::Cookie(const std::string &s, std::string::size_type cookie_start, std::string::size_type cookie_end): -	mCookie(s, cookie_start, cookie_end - cookie_start), -	mNameStart(0), mNameEnd(0), -	mValueStart(0), mValueEnd(0), -	mDomainStart(0), mDomainEnd(0), -	mPathStart(0), mPathEnd(0), -	mDead(false), mChanged(true) -{ -} - -LLPluginCookieStore::Cookie *LLPluginCookieStore::Cookie::createFromString(const std::string &s, std::string::size_type cookie_start, std::string::size_type cookie_end, const std::string &host) -{ -	Cookie *result = new Cookie(s, cookie_start, cookie_end); - -	if(!result->parse(host)) -	{ -		delete result; -		result = NULL; -	} -	 -	return result; -} - -std::string LLPluginCookieStore::Cookie::getKey() const -{ -	std::string result; -	if(mDomainEnd > mDomainStart) -	{ -		result += mCookie.substr(mDomainStart, mDomainEnd - mDomainStart); -	} -	result += ';'; -	if(mPathEnd > mPathStart) -	{ -		result += mCookie.substr(mPathStart, mPathEnd - mPathStart); -	} -	result += ';'; -	result += mCookie.substr(mNameStart, mNameEnd - mNameStart); -	return result; -} - -std::string LLPluginCookieStore::Cookie::getDomain() const -{ -	std::string result; -	if(mDomainEnd > mDomainStart) -	{ -		result += mCookie.substr(mDomainStart, mDomainEnd - mDomainStart); -	} -	return result; -} - -bool LLPluginCookieStore::Cookie::parse(const std::string &host) -{ -	bool first_field = true; - -	std::string::size_type cookie_end = mCookie.size(); -	std::string::size_type field_start = 0; - -	LL_DEBUGS("CookieStoreParse") << "parsing cookie: " << mCookie << LL_ENDL; -	while(field_start < cookie_end) -	{ -		// Finding the start of the next field requires honoring special quoting rules -		// see the definition of 'quoted-string' in rfc2616 for details -		std::string::size_type next_field_start = findFieldEnd(field_start); - -		// The end of this field should not include the terminating ';' or any trailing whitespace -		std::string::size_type field_end = mCookie.find_last_not_of("; ", next_field_start); -		if(field_end == std::string::npos || field_end < field_start) -		{ -			// This field was empty or all whitespace.  Set end = start so it shows as empty. -			field_end = field_start; -		} -		else if (field_end < next_field_start) -		{ -			// we actually want the index of the char _after_ what 'last not of' found -			++field_end; -		} -		 -		// find the start of the actual name (skip separator and possible whitespace) -		std::string::size_type name_start = mCookie.find_first_not_of("; ", field_start); -		if(name_start == std::string::npos || name_start > next_field_start) -		{ -			// Again, nothing but whitespace. -			name_start = field_start; -		} -		 -		// the name and value are separated by the first equals sign -		std::string::size_type name_value_sep = mCookie.find_first_of("=", name_start); -		if(name_value_sep == std::string::npos || name_value_sep > field_end) -		{ -			// No separator found, so this is a field without an =  -			name_value_sep = field_end; -		} -		 -		// the name end is before the name-value separator -		std::string::size_type name_end = mCookie.find_last_not_of("= ", name_value_sep); -		if(name_end == std::string::npos || name_end < name_start) -		{ -			// I'm not sure how we'd hit this case... it seems like it would have to be an empty name. -			name_end = name_start; -		} -		else if (name_end < name_value_sep) -		{ -			// we actually want the index of the char _after_ what 'last not of' found -			++name_end; -		} -		 -		// Value is between the name-value sep and the end of the field. -		std::string::size_type value_start = mCookie.find_first_not_of("= ", name_value_sep); -		if(value_start == std::string::npos || value_start > field_end) -		{ -			// All whitespace or empty value -			value_start = field_end; -		} -		std::string::size_type value_end = mCookie.find_last_not_of("; ", field_end); -		if(value_end == std::string::npos || value_end < value_start) -		{ -			// All whitespace or empty value -			value_end = value_start; -		} -		else if (value_end < field_end) -		{ -			// we actually want the index of the char _after_ what 'last not of' found -			++value_end; -		} - -		LL_DEBUGS("CookieStoreParse")  -			<< "    field name: \"" << mCookie.substr(name_start, name_end - name_start)  -			<< "\", value: \"" << mCookie.substr(value_start, value_end - value_start) << "\"" -			<< LL_ENDL; -				 -		// See whether this field is one we know -		if(first_field) -		{ -			// The first field is the name=value pair -			mNameStart = name_start; -			mNameEnd = name_end; -			mValueStart = value_start; -			mValueEnd = value_end; -			first_field = false; -		} -		else -		{ -			// Subsequent fields must come from the set in rfc2109 -			if(matchName(name_start, name_end, "expires")) -			{ -				std::string date_string(mCookie, value_start, value_end - value_start);  -				// If the cookie contains an "expires" field, it MUST contain a parsable date. -				 -				// HACK: LLDate apparently can't PARSE an rfc1123-format date, even though it can GENERATE one. -				//  The curl function curl_getdate can do this, but I'm hesitant to unilaterally introduce a curl dependency in LLDate. -#if 1 -				time_t date = curl_getdate(date_string.c_str(), NULL ); -				mDate.secondsSinceEpoch((F64)date); -				LL_DEBUGS("CookieStoreParse") << "        expire date parsed to: " << mDate.asRFC1123() << LL_ENDL; -#else -				// This doesn't work (rfc1123-format dates cause it to fail) -				if(!mDate.fromString(date_string)) -				{ -					// Date failed to parse. -					LL_WARNS("CookieStoreParse") << "failed to parse cookie's expire date: " << date << LL_ENDL; -					return false; -				} -#endif -			} -			else if(matchName(name_start, name_end, "domain")) -			{ -				mDomainStart = value_start; -				mDomainEnd = value_end; -			} -			else if(matchName(name_start, name_end, "path")) -			{ -				mPathStart = value_start; -				mPathEnd = value_end; -			} -			else if(matchName(name_start, name_end, "max-age")) -			{ -				// TODO: how should we handle this? -			} -			else if(matchName(name_start, name_end, "secure")) -			{ -				// We don't care about the value of this field (yet) -			} -			else if(matchName(name_start, name_end, "version")) -			{ -				// We don't care about the value of this field (yet) -			} -			else if(matchName(name_start, name_end, "comment")) -			{ -				// We don't care about the value of this field (yet) -			} -			else if(matchName(name_start, name_end, "httponly")) -			{ -				// We don't care about the value of this field (yet) -			} -			else -			{ -				// An unknown field is a parse failure -				LL_WARNS("CookieStoreParse") << "unexpected field name: " << mCookie.substr(name_start, name_end - name_start) << LL_ENDL; -				return false; -			} -			 -		} - -		 -		// move on to the next field, skipping this field's separator and any leading whitespace -		field_start = mCookie.find_first_not_of("; ", next_field_start); -	} -		 -	// The cookie MUST have a name -	if(mNameEnd <= mNameStart) -		return false; -	 -	// If the cookie doesn't have a domain, add the current host as the domain. -	if(mDomainEnd <= mDomainStart) -	{ -		if(host.empty()) -		{ -			// no domain and no current host -- this is a parse failure. -			return false; -		} -		 -		// Figure out whether this cookie ended with a ";" or not... -		std::string::size_type last_char = mCookie.find_last_not_of(" "); -		if((last_char != std::string::npos) && (mCookie[last_char] != ';')) -		{ -			mCookie += ";"; -		} -		 -		mCookie += " domain="; -		mDomainStart = mCookie.size(); -		mCookie += host; -		mDomainEnd = mCookie.size(); -		 -		LL_DEBUGS("CookieStoreParse") << "added domain (" << mDomainStart << " to " << mDomainEnd << "), new cookie is: " << mCookie << LL_ENDL; -	} - -	// If the cookie doesn't have a path, add "/". -	if(mPathEnd <= mPathStart) -	{ -		// Figure out whether this cookie ended with a ";" or not... -		std::string::size_type last_char = mCookie.find_last_not_of(" "); -		if((last_char != std::string::npos) && (mCookie[last_char] != ';')) -		{ -			mCookie += ";"; -		} -		 -		mCookie += " path="; -		mPathStart = mCookie.size(); -		mCookie += "/"; -		mPathEnd = mCookie.size(); -		 -		LL_DEBUGS("CookieStoreParse") << "added path (" << mPathStart << " to " << mPathEnd << "), new cookie is: " << mCookie << LL_ENDL; -	} -	 -	 -	return true; -} - -std::string::size_type LLPluginCookieStore::Cookie::findFieldEnd(std::string::size_type start, std::string::size_type end) -{ -	std::string::size_type result = start; -	 -	if(end == std::string::npos) -		end = mCookie.size(); -	 -	bool in_quotes = false; -	for(; (result < end); result++) -	{ -		switch(mCookie[result]) -		{ -			case '\\': -				if(in_quotes) -					result++; // The next character is backslash-quoted.  Skip over it. -			break; -			case '"': -				in_quotes = !in_quotes; -			break; -			case ';': -				if(!in_quotes) -					return result; -			break; -		}		 -	} -	 -	// If we got here, no ';' was found. -	return end; -} - -bool LLPluginCookieStore::Cookie::matchName(std::string::size_type start, std::string::size_type end, const char *name) -{ -	// NOTE: this assumes 'name' is already in lowercase.  The code which uses it should be able to arrange this... -	 -	while((start < end) && (*name != '\0')) -	{ -		if(tolower(mCookie[start]) != *name) -			return false; -			 -		start++; -		name++; -	} -	 -	// iff both strings hit the end at the same time, they're equal. -	return ((start == end) && (*name == '\0')); -} - -std::string LLPluginCookieStore::getAllCookies() -{ -	std::stringstream result; -	writeAllCookies(result); -	return result.str(); -} - -void LLPluginCookieStore::writeAllCookies(std::ostream& s) -{ -	cookie_map_t::iterator iter; -	for(iter = mCookies.begin(); iter != mCookies.end(); iter++) -	{ -		// Don't return expired cookies -		if(!iter->second->isDead()) -		{ -			s << (iter->second->getCookie()) << "\n"; -		} -	} - -} - -std::string LLPluginCookieStore::getPersistentCookies() -{ -	std::stringstream result; -	writePersistentCookies(result); -	return result.str(); -} - -void LLPluginCookieStore::writePersistentCookies(std::ostream& s) -{ -	cookie_map_t::iterator iter; -	for(iter = mCookies.begin(); iter != mCookies.end(); iter++) -	{ -		// Don't return expired cookies or session cookies -		if(!iter->second->isDead() && !iter->second->isSessionCookie()) -		{ -			s << iter->second->getCookie() << "\n"; -		} -	} -} - -std::string LLPluginCookieStore::getChangedCookies(bool clear_changed) -{ -	std::stringstream result; -	writeChangedCookies(result, clear_changed); -	 -	return result.str(); -} - -void LLPluginCookieStore::writeChangedCookies(std::ostream& s, bool clear_changed) -{ -	if(mHasChangedCookies) -	{ -		LL_DEBUGS() << "returning changed cookies: " << LL_ENDL; -		cookie_map_t::iterator iter; -		for(iter = mCookies.begin(); iter != mCookies.end(); ) -		{ -			cookie_map_t::iterator next = iter; -			next++; -			 -			// Only return cookies marked as "changed" -			if(iter->second->isChanged()) -			{ -				s << iter->second->getCookie() << "\n"; - -				LL_DEBUGS() << "    " << iter->second->getCookie() << LL_ENDL; - -				// If requested, clear the changed mark -				if(clear_changed) -				{ -					if(iter->second->isDead()) -					{ -						// If this cookie was previously marked dead, it needs to be removed entirely.	 -						delete iter->second; -						mCookies.erase(iter); -					} -					else -					{ -						// Not dead, just mark as not changed. -						iter->second->setChanged(false); -					} -				} -			} -			 -			iter = next; -		} -	} -	 -	if(clear_changed) -		mHasChangedCookies = false; -} - -void LLPluginCookieStore::setAllCookies(const std::string &cookies, bool mark_changed) -{ -	clearCookies(); -	setCookies(cookies, mark_changed); -} - -void LLPluginCookieStore::readAllCookies(std::istream& s, bool mark_changed) -{ -	clearCookies(); -	readCookies(s, mark_changed); -} -	 -void LLPluginCookieStore::setCookies(const std::string &cookies, bool mark_changed) -{ -	std::string::size_type start = 0; - -	while(start != std::string::npos) -	{ -		std::string::size_type end = cookies.find_first_of("\r\n", start); -		if(end > start) -		{ -			// The line is non-empty.  Try to create a cookie from it. -			setOneCookie(cookies, start, end, mark_changed); -		} -		start = cookies.find_first_not_of("\r\n ", end); -	} -} - -void LLPluginCookieStore::setCookiesFromHost(const std::string &cookies, const std::string &host, bool mark_changed) -{ -	std::string::size_type start = 0; - -	while(start != std::string::npos) -	{ -		std::string::size_type end = cookies.find_first_of("\r\n", start); -		if(end > start) -		{ -			// The line is non-empty.  Try to create a cookie from it. -			setOneCookie(cookies, start, end, mark_changed, host); -		} -		start = cookies.find_first_not_of("\r\n ", end); -	} -} -			 -void LLPluginCookieStore::readCookies(std::istream& s, bool mark_changed) -{ -	std::string line; -	while(s.good() && !s.eof()) -	{ -		std::getline(s, line); -		if(!line.empty()) -		{ -			// Try to create a cookie from this line. -			setOneCookie(line, 0, std::string::npos, mark_changed); -		} -	} -} - -std::string LLPluginCookieStore::quoteString(const std::string &s) -{ -	std::stringstream result; -	 -	result << '"'; -	 -	for(std::string::size_type i = 0; i < s.size(); ++i) -	{ -		char c = s[i]; -		switch(c) -		{ -			// All these separators need to be quoted in HTTP headers, according to section 2.2 of rfc 2616: -			case '(': case ')': case '<': case '>': case '@': -			case ',': case ';': case ':': case '\\': case '"': -			case '/': case '[': case ']': case '?': case '=': -			case '{': case '}':	case ' ': case '\t': -				result << '\\'; -			break; -		} -		 -		result << c; -	} -	 -	result << '"'; -	 -	return result.str(); -} - -std::string LLPluginCookieStore::unquoteString(const std::string &s) -{ -	std::stringstream result; -	 -	bool in_quotes = false; -	 -	for(std::string::size_type i = 0; i < s.size(); ++i) -	{ -		char c = s[i]; -		switch(c) -		{ -			case '\\': -				if(in_quotes) -				{ -					// The next character is backslash-quoted.  Pass it through untouched. -					++i;  -					if(i < s.size()) -					{ -						result << s[i]; -					} -					continue; -				} -			break; -			case '"': -				in_quotes = !in_quotes; -				continue; -			break; -		} -		 -		result << c; -	} -	 -	return result.str(); -} - -// The flow for deleting a cookie is non-obvious enough that I should call it out here... -// Deleting a cookie is done by setting a cookie with the same name, path, and domain, but with an expire timestamp in the past. -// (This is exactly how a web server tells a browser to delete a cookie.) -// When deleting with mark_changed set to true, this replaces the existing cookie in the list with an entry that's marked both dead and changed. -// Some time later when writeChangedCookies() is called with clear_changed set to true, the dead cookie is deleted from the list after being returned, so that the -// delete operation (in the form of the expired cookie) is passed along. -void LLPluginCookieStore::setOneCookie(const std::string &s, std::string::size_type cookie_start, std::string::size_type cookie_end, bool mark_changed, const std::string &host) -{ -	Cookie *cookie = Cookie::createFromString(s, cookie_start, cookie_end, host); -	if(cookie) -	{ -		LL_DEBUGS("CookieStoreUpdate") << "setting cookie: " << cookie->getCookie() << LL_ENDL; -		 -		// Create a key for this cookie -		std::string key = cookie->getKey(); -		 -		// Check to see whether this cookie should have expired -		if(!cookie->isSessionCookie() && (cookie->getDate() < LLDate::now())) -		{ -			// This cookie has expired. -			if(mark_changed) -			{ -				// If we're marking cookies as changed, we should keep it anyway since we'll need to send it out with deltas. -				cookie->setDead(true); -				LL_DEBUGS("CookieStoreUpdate") << "    marking dead" << LL_ENDL; -			} -			else -			{ -				// If we're not marking cookies as changed, we don't need to keep this cookie at all. -				// If the cookie was already in the list, delete it. -				removeCookie(key); - -				delete cookie; -				cookie = NULL; - -				LL_DEBUGS("CookieStoreUpdate") << "    removing" << LL_ENDL; -			} -		} -		 -		if(cookie) -		{ -			// If it already exists in the map, replace it. -			cookie_map_t::iterator iter = mCookies.find(key); -			if(iter != mCookies.end()) -			{ -				if(iter->second->getCookie() == cookie->getCookie()) -				{ -					// The new cookie is identical to the old -- don't mark as changed. -					// Just leave the old one in the map. -					delete cookie; -					cookie = NULL; - -					LL_DEBUGS("CookieStoreUpdate") << "    unchanged" << LL_ENDL; -				} -				else -				{ -					// A matching cookie was already in the map.  Replace it. -					delete iter->second; -					iter->second = cookie; -					 -					cookie->setChanged(mark_changed); -					if(mark_changed) -						mHasChangedCookies = true; - -					LL_DEBUGS("CookieStoreUpdate") << "    replacing" << LL_ENDL; -				} -			} -			else -			{ -				// The cookie wasn't in the map.  Insert it. -				mCookies.insert(std::make_pair(key, cookie)); -				 -				cookie->setChanged(mark_changed); -				if(mark_changed) -					mHasChangedCookies = true; - -				LL_DEBUGS("CookieStoreUpdate") << "    adding" << LL_ENDL; -			} -		} -	} -	else -	{ -		LL_WARNS("CookieStoreUpdate") << "failed to parse cookie: " << s.substr(cookie_start, cookie_end - cookie_start) << LL_ENDL; -	} - -} - -void LLPluginCookieStore::clearCookies() -{ -	std::for_each(mCookies.begin(), mCookies.end(), DeletePairedPointer()); -	mCookies.clear(); -} - -void LLPluginCookieStore::removeCookie(const std::string &key) -{ -	cookie_map_t::iterator iter = mCookies.find(key); -	if(iter != mCookies.end()) -	{ -		delete iter->second; -		mCookies.erase(iter); -	} -} - -void LLPluginCookieStore::removeCookiesByDomain(const std::string &domain) -{ -	cookie_map_t::iterator iter = mCookies.begin(); -	while(iter != mCookies.end()) -	{  -		if(iter->second->getDomain() == domain) -		{ -            cookie_map_t::iterator doErase = iter; -            iter++; -			delete doErase->second; -			mCookies.erase(doErase); -		} -        else -        { -            iter++; -        } -	} -} diff --git a/indra/llplugin/llplugincookiestore.h b/indra/llplugin/llplugincookiestore.h deleted file mode 100644 index a2fdeab647..0000000000 --- a/indra/llplugin/llplugincookiestore.h +++ /dev/null @@ -1,123 +0,0 @@ -/**  - * @file llplugincookiestore.h - * @brief LLPluginCookieStore provides central storage for http cookies used by plugins - * - * @cond - * $LicenseInfo:firstyear=2010&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - * @endcond - */ - -#ifndef LL_LLPLUGINCOOKIESTORE_H -#define LL_LLPLUGINCOOKIESTORE_H - -#include "lldate.h" -#include <map> -#include <string> -#include <iostream> - -class LLPluginCookieStore -{ -	LOG_CLASS(LLPluginCookieStore); -public: -	LLPluginCookieStore(); -	~LLPluginCookieStore(); - -	// gets all cookies currently in storage -- use when initializing a plugin -	std::string getAllCookies(); -	void writeAllCookies(std::ostream& s); -	 -	// gets only persistent cookies (i.e. not session cookies) -- use when writing cookies to a file -	std::string getPersistentCookies(); -	void writePersistentCookies(std::ostream& s); -	 -	// gets cookies which are marked as "changed" -- use when sending periodic updates to plugins -	std::string getChangedCookies(bool clear_changed = true); -	void writeChangedCookies(std::ostream& s, bool clear_changed = true); -	 -	// (re)initializes internal data structures and bulk-sets cookies -- use when reading cookies from a file -	void setAllCookies(const std::string &cookies, bool mark_changed = false); -	void readAllCookies(std::istream& s, bool mark_changed = false); -	 -	// sets one or more cookies (without reinitializing anything) -- use when receiving cookies from a plugin -	void setCookies(const std::string &cookies, bool mark_changed = true); -	void readCookies(std::istream& s, bool mark_changed = true); - -	// sets one or more cookies (without reinitializing anything), supplying a hostname the cookies came from -- use when setting a cookie manually -	void setCookiesFromHost(const std::string &cookies, const std::string &host, bool mark_changed = true); - -	// quote or unquote a string as per the definition of 'quoted-string' in rfc2616 -	static std::string quoteString(const std::string &s); -	static std::string unquoteString(const std::string &s); - -	void removeCookiesByDomain(const std::string &domain); -	 -private: - -	void setOneCookie(const std::string &s, std::string::size_type cookie_start, std::string::size_type cookie_end, bool mark_changed, const std::string &host = LLStringUtil::null); - -	class Cookie -	{ -	public: -		static Cookie *createFromString(const std::string &s, std::string::size_type cookie_start = 0, std::string::size_type cookie_end = std::string::npos, const std::string &host = LLStringUtil::null); -		 -		// Construct a string from the cookie that uniquely represents it, to be used as a key in a std::map. -		std::string getKey() const; -		std::string getDomain() const; -		 -		const std::string &getCookie() const { return mCookie; }; -		bool isSessionCookie() const { return mDate.isNull(); }; - -		bool isDead() const { return mDead; }; -		void setDead(bool dead) { mDead = dead; }; -		 -		bool isChanged() const { return mChanged; }; -		void setChanged(bool changed) { mChanged = changed; }; - -		const LLDate &getDate() const { return mDate; }; -		 -	private: -		Cookie(const std::string &s, std::string::size_type cookie_start = 0, std::string::size_type cookie_end = std::string::npos); -		bool parse(const std::string &host); -		std::string::size_type findFieldEnd(std::string::size_type start = 0, std::string::size_type end = std::string::npos); -		bool matchName(std::string::size_type start, std::string::size_type end, const char *name); -		 -		std::string mCookie;	// The full cookie, in RFC 2109 string format -		LLDate mDate;			// The expiration date of the cookie.  For session cookies, this will be a null date (mDate.isNull() is true). -		// Start/end indices of various parts of the cookie string.  Stored as indices into the string to save space and time. -		std::string::size_type mNameStart, mNameEnd; -		std::string::size_type mValueStart, mValueEnd; -		std::string::size_type mDomainStart, mDomainEnd; -		std::string::size_type mPathStart, mPathEnd; -		bool mDead; -		bool mChanged; -	}; -	 -	typedef std::map<std::string, Cookie*> cookie_map_t; -	 -	cookie_map_t mCookies; -	bool mHasChangedCookies; -	 -	void clearCookies(); -	void removeCookie(const std::string &key); -}; - -#endif // LL_LLPLUGINCOOKIESTORE_H diff --git a/indra/llplugin/tests/llplugincookiestore_test.cpp b/indra/llplugin/tests/llplugincookiestore_test.cpp deleted file mode 100644 index c2cb236cba..0000000000 --- a/indra/llplugin/tests/llplugincookiestore_test.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/**  - * @file llplugincookiestore_test.cpp - * @brief Unit tests for LLPluginCookieStore. - * - * @cond - * $LicenseInfo:firstyear=2010&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - * @endcond - */ - -#include "linden_common.h" -#include <list> -#include "../test/lltut.h" - -#include "../llplugincookiestore.h" - - -namespace tut -{ -	// Main Setup -	struct LLPluginCookieStoreFixture -	{ -		LLPluginCookieStoreFixture() -		{ -			// We need dates definitively in the past and the future to properly test cookie expiration. -			LLDate now = LLDate::now();  -			LLDate past(now.secondsSinceEpoch() - (60.0 * 60.0 * 24.0));	// 1 day in the past -			LLDate future(now.secondsSinceEpoch() + (60.0 * 60.0 * 24.0));	// 1 day in the future -			 -			mPastString = past.asRFC1123(); -			mFutureString = future.asRFC1123(); -		} -		 -		std::string mPastString; -		std::string mFutureString; -		LLPluginCookieStore mCookieStore; -		 -		// List of cookies used for validation -		std::list<std::string> mCookies; -		 -		// This sets up mCookies from a string returned by one of the functions in LLPluginCookieStore -		void setCookies(const std::string &cookies) -		{ -			mCookies.clear(); -			std::string::size_type start = 0; - -			while(start != std::string::npos) -			{ -				std::string::size_type end = cookies.find_first_of("\r\n", start); -				if(end > start) -				{ -					std::string line(cookies, start, end - start); -					if(line.find_first_not_of("\r\n\t ") != std::string::npos) -					{ -						// The line has some non-whitespace characters.  Save it to the list. -						mCookies.push_back(std::string(cookies, start, end - start)); -					} -				} -				start = cookies.find_first_not_of("\r\n ", end); -			} -		} -		 -		// This ensures that a cookie matching the one passed is in the list. -		void ensureCookie(const std::string &cookie) -		{ -			std::list<std::string>::iterator iter; -			for(iter = mCookies.begin(); iter != mCookies.end(); iter++) -			{ -				if(*iter == cookie) -				{ -					// Found the cookie -					// TODO: this should do a smarter equality comparison on the two cookies, instead of just a string compare. -					return; -				} -			} -			 -			// Didn't find this cookie -			std::string message = "cookie not found: "; -			message += cookie; -			ensure(message, false); -		} -		 -		// This ensures that the number of cookies in the list matches what's expected. -		void ensureSize(const std::string &message, size_t size) -		{ -			if(mCookies.size() != size) -			{ -				std::stringstream full_message; -				 -				full_message << message << " (expected " << size << ", actual " << mCookies.size() << ")"; -				ensure(full_message.str(), false); -			} -		} -	}; -	 -	typedef test_group<LLPluginCookieStoreFixture> factory; -	typedef factory::object object; -	factory tf("LLPluginCookieStore"); - -	// Tests -	template<> template<> -	void object::test<1>() -	{ -		// Test 1: cookie uniqueness and update lists. -		// Valid, distinct cookies: -		 -		std::string cookie01 = "cookieA=value; domain=example.com; path=/"; -		std::string cookie02 = "cookieB=value; Domain=example.com; Path=/; Max-Age=10; Secure; Version=1; Comment=foo!; HTTPOnly"; // cookie with every supported field, in different cases. -		std::string cookie03 = "cookieA=value; domain=foo.example.com; path=/"; // different domain -		std::string cookie04 = "cookieA=value; domain=example.com; path=/bar/"; // different path -		std::string cookie05 = "cookieC; domain=example.com; path=/"; // empty value -		std::string cookie06 = "cookieD=value; domain=example.com; path=/; expires="; // different name, persistent cookie -		cookie06 += mFutureString; -		 -		mCookieStore.setCookies(cookie01); -		mCookieStore.setCookies(cookie02); -		mCookieStore.setCookies(cookie03); -		mCookieStore.setCookies(cookie04); -		mCookieStore.setCookies(cookie05); -		mCookieStore.setCookies(cookie06); -		 -		// Invalid cookies (these will get parse errors and not be added to the store) - -		std::string badcookie01 = "cookieD=value; domain=example.com; path=/; foo=bar"; // invalid field name -		std::string badcookie02 = "cookieE=value; path=/"; // no domain - -		mCookieStore.setCookies(badcookie01); -		mCookieStore.setCookies(badcookie02); -		 -		// All cookies added so far should have been marked as "changed" -		setCookies(mCookieStore.getChangedCookies()); -		ensureSize("count of changed cookies", 6); -		ensureCookie(cookie01); -		ensureCookie(cookie02); -		ensureCookie(cookie03); -		ensureCookie(cookie04); -		ensureCookie(cookie05); -		ensureCookie(cookie06); -		 -		// Save off the current state of the cookie store (we'll restore it later) -		std::string savedCookies = mCookieStore.getAllCookies(); -		 -		// Test replacing cookies -		std::string cookie01a = "cookieA=newvalue; domain=example.com; path=/";	// updated value -		std::string cookie02a = "cookieB=newvalue; domain=example.com; path=/; expires="; // remove cookie (by setting an expire date in the past) -		cookie02a += mPastString; -		 -		mCookieStore.setCookies(cookie01a); -		mCookieStore.setCookies(cookie02a); - -		// test for getting changed cookies -		setCookies(mCookieStore.getChangedCookies()); -		ensureSize("count of updated cookies", 2); -		ensureCookie(cookie01a); -		ensureCookie(cookie02a); -		 -		// and for the state of the store after getting changed cookies -		setCookies(mCookieStore.getAllCookies()); -		ensureSize("count of valid cookies", 5); -		ensureCookie(cookie01a); -		ensureCookie(cookie03); -		ensureCookie(cookie04); -		ensureCookie(cookie05); -		ensureCookie(cookie06); - -		// Check that only the persistent cookie is returned here -		setCookies(mCookieStore.getPersistentCookies()); -		ensureSize("count of persistent cookies", 1); -		ensureCookie(cookie06); - -		// Restore the cookie store to a previous state and verify -		mCookieStore.setAllCookies(savedCookies); -		 -		// Since setAllCookies defaults to not marking cookies as changed, this list should be empty. -		setCookies(mCookieStore.getChangedCookies()); -		ensureSize("count of changed cookies after restore", 0); - -		// Verify that the restore worked as it should have. -		setCookies(mCookieStore.getAllCookies()); -		ensureSize("count of restored cookies", 6); -		ensureCookie(cookie01); -		ensureCookie(cookie02); -		ensureCookie(cookie03); -		ensureCookie(cookie04); -		ensureCookie(cookie05); -		ensureCookie(cookie06); -	} - -} diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index f3d7762a08..d6a6232221 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -38,6 +38,7 @@  #include "media_plugin_base.h"  #include <functional> +#include <chrono>  #include "dullahan.h" @@ -64,12 +65,12 @@ private:  	void onLoadStartCallback();  	void onRequestExitCallback();  	void onLoadEndCallback(int httpStatusCode); +	void onLoadError(int status, const std::string error_text);  	void onAddressChangeCallback(std::string url);  	void onNavigateURLCallback(std::string url, std::string target);  	bool onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password);  	void onCursorChangedCallback(dullahan::ECursorType type); -	void onFileDownloadCallback(std::string filename); -	const std::string onFileDialogCallback(); +	const std::vector<std::string> onFileDialog(dullahan::EFileDialogType dialog_type, const std::string dialog_title, const std::string default_file, const std::string dialog_accept_filter, bool& use_default);  	void postDebugMessage(const std::string& msg);  	void authResponse(LLPluginMessage &message); @@ -95,7 +96,9 @@ private:  	bool mCanPaste;  	std::string mCachePath;  	std::string mCookiePath; -	std::string mPickedFile; +	std::string mCefLogFile; +	bool mCefLogVerbose; +	std::vector<std::string> mPickedFiles;  	VolumeCatcher mVolumeCatcher;  	F32 mCurVolume;  	dullahan* mCEFLib; @@ -115,7 +118,7 @@ MediaPluginBase(host_send_func, host_user_data)  	mCookiesEnabled = true;  	mPluginsEnabled = false;  	mJavascriptEnabled = true; -	mDisableGPU = true; +	mDisableGPU = false;  	mUserAgentSubtring = "";  	mAuthUsername = "";  	mAuthPassword = ""; @@ -125,7 +128,9 @@ MediaPluginBase(host_send_func, host_user_data)  	mCanPaste = false;  	mCachePath = "";  	mCookiePath = ""; -	mPickedFile = ""; +	mCefLogFile = ""; +	mCefLogVerbose = false; +	mPickedFiles.clear();  	mCurVolume = 0.0;  	mCEFLib = new dullahan(); @@ -166,6 +171,10 @@ void MediaPluginCEF::onPageChangedCallback(const unsigned char* pixels, int x, i  		{  			memcpy(mPixels, pixels, mWidth * mHeight * mDepth);  		} +		else +		{ +			mCEFLib->setSize(mWidth, mHeight); +		}  		setDirty(0, 0, mWidth, mHeight);  	}  } @@ -208,6 +217,21 @@ void MediaPluginCEF::onLoadStartCallback()  	sendMessage(message);  } +///////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginCEF::onLoadError(int status, const std::string error_text) +{ +	std::stringstream msg; + +	msg << "<b>Loading error!</b>"; +	msg << "<p>"; +	msg << "Message: " << error_text; +	msg << "<br>"; +	msg << "Code: " << status; + +	mCEFLib->showBrowserMessage(msg.str()); +} +  ////////////////////////////////////////////////////////////////////////////////  //  void MediaPluginCEF::onRequestExitCallback() @@ -246,7 +270,6 @@ void MediaPluginCEF::onNavigateURLCallback(std::string url, std::string target)  	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_href");  	message.setValue("uri", url);  	message.setValue("target", target); -	message.setValue("uuid", "");	// not used right now  	sendMessage(message);  } @@ -285,30 +308,52 @@ bool MediaPluginCEF::onHTTPAuthCallback(const std::string host, const std::strin  ////////////////////////////////////////////////////////////////////////////////  // -void MediaPluginCEF::onFileDownloadCallback(const std::string filename) +const std::vector<std::string> MediaPluginCEF::onFileDialog(dullahan::EFileDialogType dialog_type, const std::string dialog_title, const std::string default_file, std::string dialog_accept_filter, bool& use_default)  { -	mAuthOK = false; +	// do not use the default CEF file picker +	use_default = false; -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "file_download"); -	message.setValue("filename", filename); +	if (dialog_type == dullahan::FD_OPEN_FILE) +	{ +		mPickedFiles.clear(); -	sendMessage(message); -} +		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file"); +		message.setValueBoolean("blocking_request", true); +		message.setValueBoolean("multiple_files", false); -//////////////////////////////////////////////////////////////////////////////// -// -const std::string MediaPluginCEF::onFileDialogCallback() -{ -	mPickedFile.clear(); +		sendMessage(message); -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file"); -	message.setValueBoolean("blocking_request", true); +		return mPickedFiles; +	} +	else if (dialog_type == dullahan::FD_OPEN_MULTIPLE_FILES) +	{ +		mPickedFiles.clear(); -	sendMessage(message); +		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file"); +		message.setValueBoolean("blocking_request", true); +		message.setValueBoolean("multiple_files", true); + +		sendMessage(message); + +		return mPickedFiles; +	} +	else if (dialog_type == dullahan::FD_SAVE_FILE) +	{ +		mAuthOK = false; + +		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "file_download"); +		message.setValue("filename", default_file); -	return mPickedFile; +		sendMessage(message); + +		return std::vector<std::string>(); +	} + +	return std::vector<std::string>();  } +//////////////////////////////////////////////////////////////////////////////// +//  void MediaPluginCEF::onCursorChangedCallback(dullahan::ECursorType type)  {  	std::string name = ""; @@ -341,6 +386,8 @@ void MediaPluginCEF::onCursorChangedCallback(dullahan::ECursorType type)  	sendMessage(message);  } +//////////////////////////////////////////////////////////////////////////////// +//  void MediaPluginCEF::authResponse(LLPluginMessage &message)  {  	mAuthOK = message.getValueBoolean("ok"); @@ -373,7 +420,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)  				versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION;  				message.setValueLLSD("versions", versions); -				std::string plugin_version = "CEF plugin 1.1.3"; +				std::string plugin_version = "CEF plugin 1.1.412";  				message.setValue("plugin_version", plugin_version);  				sendMessage(message);  			} @@ -439,17 +486,17 @@ void MediaPluginCEF::receiveMessage(const char* message_string)  				mCEFLib->setOnTitleChangeCallback(std::bind(&MediaPluginCEF::onTitleChangeCallback, this, std::placeholders::_1));  				mCEFLib->setOnLoadStartCallback(std::bind(&MediaPluginCEF::onLoadStartCallback, this));  				mCEFLib->setOnLoadEndCallback(std::bind(&MediaPluginCEF::onLoadEndCallback, this, std::placeholders::_1)); +				mCEFLib->setOnLoadErrorCallback(std::bind(&MediaPluginCEF::onLoadError, this, std::placeholders::_1, std::placeholders::_2));  				mCEFLib->setOnAddressChangeCallback(std::bind(&MediaPluginCEF::onAddressChangeCallback, this, std::placeholders::_1));  				mCEFLib->setOnNavigateURLCallback(std::bind(&MediaPluginCEF::onNavigateURLCallback, this, std::placeholders::_1, std::placeholders::_2));  				mCEFLib->setOnHTTPAuthCallback(std::bind(&MediaPluginCEF::onHTTPAuthCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); -				mCEFLib->setOnFileDownloadCallback(std::bind(&MediaPluginCEF::onFileDownloadCallback, this, std::placeholders::_1)); -				mCEFLib->setOnFileDialogCallback(std::bind(&MediaPluginCEF::onFileDialogCallback, this)); +				mCEFLib->setOnFileDialogCallback(std::bind(&MediaPluginCEF::onFileDialog, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));  				mCEFLib->setOnCursorChangedCallback(std::bind(&MediaPluginCEF::onCursorChangedCallback, this, std::placeholders::_1));  				mCEFLib->setOnRequestExitCallback(std::bind(&MediaPluginCEF::onRequestExitCallback, this));  				dullahan::dullahan_settings settings;  				settings.accept_language_list = mHostLanguage; -				settings.background_color = 0xffffffff; +				settings.background_color = 0xff282828;  				settings.cache_enabled = true;  				settings.cache_path = mCachePath;  				settings.cookie_store_path = mCookiePath; @@ -468,6 +515,8 @@ void MediaPluginCEF::receiveMessage(const char* message_string)  				settings.plugins_enabled = mPluginsEnabled;  				settings.user_agent_substring = mCEFLib->makeCompatibleUserAgentString(mUserAgentSubtring);  				settings.webgl_enabled = true; +				settings.log_file = mCefLogFile; +				settings.log_verbose = mCefLogVerbose;  				std::vector<std::string> custom_schemes(1, "secondlife");  				mCEFLib->setCustomSchemes(custom_schemes); @@ -497,8 +546,11 @@ void MediaPluginCEF::receiveMessage(const char* message_string)  			{  				std::string user_data_path_cache = message_in.getValue("cache_path");  				std::string user_data_path_cookies = message_in.getValue("cookies_path"); +  				mCachePath = user_data_path_cache + "cef_cache";  				mCookiePath = user_data_path_cookies + "cef_cookies"; +				mCefLogFile = message_in.getValue("cef_log_file"); +				mCefLogVerbose = message_in.getValueBoolean("cef_verbose_log");  			}  			else if (message_name == "size_change")  			{ @@ -520,11 +572,11 @@ void MediaPluginCEF::receiveMessage(const char* message_string)  						mTextureWidth = texture_width;  						mTextureHeight = texture_height; + +						mCEFLib->setSize(mWidth, mHeight);  					};  				}; -				mCEFLib->setSize(mWidth, mHeight); -  				LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");  				message.setValue("name", name);  				message.setValueS32("width", width); @@ -650,7 +702,14 @@ void MediaPluginCEF::receiveMessage(const char* message_string)  			}  			if (message_name == "pick_file_response")  			{ -				mPickedFile = message_in.getValue("file"); +				LLSD file_list_llsd = message_in.getValueLLSD("file_list"); + +				LLSD::array_const_iterator iter = file_list_llsd.beginArray(); +				LLSD::array_const_iterator end = file_list_llsd.endArray(); +				for (; iter != end; ++iter) +				{ +					mPickedFiles.push_back(((*iter).asString())); +				}  			}  			if (message_name == "auth_response")  			{ @@ -697,6 +756,10 @@ void MediaPluginCEF::receiveMessage(const char* message_string)  			{  				mCookiesEnabled = message_in.getValueBoolean("enable");  			} +			else if (message_name == "clear_cookies") +			{ +				mCEFLib->deleteAllCookies(); +			}  			else if (message_name == "set_user_agent")  			{  				mUserAgentSubtring = message_in.getValue("user_agent"); diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index dd07972249..1689f66e8b 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -16155,6 +16155,17 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>CefVerboseLog</key> +    <map> +      <key>Comment</key> +      <string>Enable/disable CEF verbose loggingk</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>  </map>  </llsd> diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 464e216cf0..eed052b82a 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1940,8 +1940,6 @@ bool LLAppViewer::cleanup()  	LLAvatarIconIDCache::getInstance()->save(); -	LLViewerMedia::saveCookieFile(); -  	// Stop the plugin read thread if it's running.  	LLPluginProcessParent::setUseReadThread(false); @@ -3179,8 +3177,14 @@ LLSD LLAppViewer::getViewerInfo() const  	cef_ver_codec << " / CEF: ";  	cef_ver_codec << CEF_VERSION; -	cef_ver_codec << " / Chrome: "; +	cef_ver_codec << " / Chromium: ";  	cef_ver_codec << CHROME_VERSION_MAJOR; +	cef_ver_codec << "."; +	cef_ver_codec << CHROME_VERSION_MINOR; +	cef_ver_codec << "."; +	cef_ver_codec << CHROME_VERSION_BUILD; +	cef_ver_codec << "."; +	cef_ver_codec << CHROME_VERSION_PATCH;  	info["LIBCEF_VERSION"] = cef_ver_codec.str();  #else diff --git a/indra/newview/llfloaterfacebook.cpp b/indra/newview/llfloaterfacebook.cpp index b1d6d8be82..e84cbc289f 100644 --- a/indra/newview/llfloaterfacebook.cpp +++ b/indra/newview/llfloaterfacebook.cpp @@ -1,4 +1,4 @@ -/**  +/**  * @file llfloaterfacebook.cpp  * @brief Implementation of llfloaterfacebook  * @author Gilbert@lindenlab.com @@ -41,7 +41,6 @@  #include "llresmgr.h"		// LLLocale  #include "llsdserialize.h"  #include "llloadingindicator.h" -#include "llplugincookiestore.h"  #include "llslurl.h"  #include "lltrans.h"  #include "llsnapshotlivepreview.h" @@ -296,16 +295,11 @@ void LLFacebookStatusPanel::showConnectedLayout()  void LLFacebookStatusPanel::onConnect()  {      LLFacebookConnect::instance().checkConnectionToFacebook(true); - -    //Clear only the facebook browser cookies so that the facebook login screen appears -    LLViewerMedia::getCookieStore()->removeCookiesByDomain(".facebook.com");  }  void LLFacebookStatusPanel::onDisconnect()  {      LLFacebookConnect::instance().disconnectFromFacebook(); - -    LLViewerMedia::getCookieStore()->removeCookiesByDomain(".facebook.com");  }  void LLFacebookStatusPanel::clearAndClose() @@ -810,7 +804,7 @@ void LLFacebookCheckinPanel::sendCheckin()      LLAgentUI::buildSLURL(slurl);      std::string slurl_string = slurl.getSLURLString(); -    // Use a valid http:// URL if the scheme is secondlife://  +    // Use a valid http:// URL if the scheme is secondlife://      LLURI slurl_uri(slurl_string);      if (slurl_uri.scheme() == LLSLURL::SLURL_SECONDLIFE_SCHEME)      { diff --git a/indra/newview/llfloaterflickr.cpp b/indra/newview/llfloaterflickr.cpp index 15b7c7fafa..69a92b2b54 100644 --- a/indra/newview/llfloaterflickr.cpp +++ b/indra/newview/llfloaterflickr.cpp @@ -40,7 +40,6 @@  #include "llresmgr.h"		// LLLocale  #include "llsdserialize.h"  #include "llloadingindicator.h" -#include "llplugincookiestore.h"  #include "llslurl.h"  #include "lltrans.h"  #include "llsnapshotlivepreview.h" @@ -660,16 +659,11 @@ void LLFlickrAccountPanel::showConnectedLayout()  void LLFlickrAccountPanel::onConnect()  {  	LLFlickrConnect::instance().checkConnectionToFlickr(true); - -	//Clear only the flickr browser cookies so that the flickr login screen appears -	LLViewerMedia::getCookieStore()->removeCookiesByDomain(".flickr.com");   }  void LLFlickrAccountPanel::onDisconnect()  {  	LLFlickrConnect::instance().disconnectFromFlickr(); - -	LLViewerMedia::getCookieStore()->removeCookiesByDomain(".flickr.com");   }  //////////////////////// diff --git a/indra/newview/llfloatertwitter.cpp b/indra/newview/llfloatertwitter.cpp index 803c80ac1a..2b33bc6935 100644 --- a/indra/newview/llfloatertwitter.cpp +++ b/indra/newview/llfloatertwitter.cpp @@ -41,7 +41,6 @@  #include "llresmgr.h"		// LLLocale  #include "llsdserialize.h"  #include "llloadingindicator.h" -#include "llplugincookiestore.h"  #include "llslurl.h"  #include "lltrans.h"  #include "llsnapshotlivepreview.h" @@ -683,16 +682,11 @@ void LLTwitterAccountPanel::showConnectedLayout()  void LLTwitterAccountPanel::onConnect()  {  	LLTwitterConnect::instance().checkConnectionToTwitter(true); - -	//Clear only the twitter browser cookies so that the twitter login screen appears -	LLViewerMedia::getCookieStore()->removeCookiesByDomain(".twitter.com");   }  void LLTwitterAccountPanel::onDisconnect()  {  	LLTwitterConnect::instance().disconnectFromTwitter(); - -	LLViewerMedia::getCookieStore()->removeCookiesByDomain(".twitter.com");   }  //////////////////////// diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index a8025906c7..7f6955d08c 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -1022,7 +1022,7 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)  			// try as slurl first  			if (!LLURLDispatcher::dispatch(url, "clicked", NULL, mTrusted))  			{ -				LLWeb::loadURL(url, target, std::string()); +				LLWeb::loadURL(url, target, uuid);  			}  			// CP: removing this code because we no longer support popups so this breaks the flow. diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 7ea6a14e6b..8c5cad5af0 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -965,9 +965,6 @@ bool idle_startup()  		// Load Avatars icons cache  		LLAvatarIconIDCache::getInstance()->load(); -		// Load media plugin cookies -		LLViewerMedia::loadCookieFile(); -  		LLRenderMuteList::getInstance()->loadFromFile();  		//------------------------------------------------- diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 474f3de664..422c1a2328 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -50,7 +50,6 @@  #include "llpanelprofile.h"  #include "llparcel.h"  #include "llpluginclassmedia.h" -#include "llplugincookiestore.h"  #include "llurldispatcher.h"  #include "lluuid.h"  #include "llversioninfo.h" @@ -154,7 +153,6 @@ LLViewerMediaObserver::~LLViewerMediaObserver()  } -LLPluginCookieStore *LLViewerMedia::sCookieStore = NULL;  LLURL LLViewerMedia::sOpenIDURL;  std::string LLViewerMedia::sOpenIDCookie;  LLPluginClassMedia* LLViewerMedia::sSpareBrowserMediaSource = NULL; @@ -169,8 +167,6 @@ static F64 sLowestLoadableImplInterest = 0.0f;  static bool sAnyMediaShowing = false;  static bool sAnyMediaPlaying = false;  static boost::signals2::connection sTeleportFinishConnection; -static std::string sUpdatedCookies; -static const char *PLUGIN_COOKIE_FILE_NAME = "plugin_cookies.txt";  //////////////////////////////////////////////////////////////////////////////////////////  static void add_media_impl(LLViewerMediaImpl* media) @@ -610,12 +606,6 @@ void LLViewerMedia::updateMedia(void *dummy_arg)  	sAnyMediaShowing = false;  	sAnyMediaPlaying = false; -	sUpdatedCookies = getCookieStore()->getChangedCookies(); -	if(!sUpdatedCookies.empty()) -	{ -		LL_DEBUGS() << "updated cookies will be sent to all loaded plugins: " << LL_ENDL; -		LL_DEBUGS() << sUpdatedCookies << LL_ENDL; -	}  	impl_list::iterator iter = sViewerMediaImplList.begin();  	impl_list::iterator end = sViewerMediaImplList.end(); @@ -1059,64 +1049,6 @@ void LLViewerMedia::clearAllCookies()  			pimpl->mMediaSource->clear_cookies();  		}  	} - -	// Clear all cookies from the cookie store -	getCookieStore()->setAllCookies(""); - -	// FIXME: this may not be sufficient, since the on-disk cookie file won't get written until some browser instance exits cleanly. -	// It also won't clear cookies for other accounts, or for any account if we're not logged in, and won't do anything at all if there are no webkit plugins loaded. -	// Until such time as we can centralize cookie storage, the following hack should cover these cases: - -	// HACK: Look for cookie files in all possible places and delete them. -	// NOTE: this assumes knowledge of what happens inside the webkit plugin (it's what adds 'browser_profile' to the path and names the cookie file) - -	// Places that cookie files can be: -	// <getOSUserAppDir>/browser_profile/cookies -	// <getOSUserAppDir>/first_last/browser_profile/cookies  (note that there may be any number of these!) -	// <getOSUserAppDir>/first_last/plugin_cookies.txt  (note that there may be any number of these!) - -	std::string base_dir = gDirUtilp->getOSUserAppDir() + gDirUtilp->getDirDelimiter(); -	std::string target; -	std::string filename; - -	LL_DEBUGS() << "base dir = " << base_dir << LL_ENDL; - -	// The non-logged-in version is easy -	target = base_dir; -	target += "browser_profile"; -	target += gDirUtilp->getDirDelimiter(); -	target += "cookies"; -	LL_DEBUGS() << "target = " << target << LL_ENDL; -	if(LLFile::isfile(target)) -	{ -		LLFile::remove(target); -	} - -	// the hard part: iterate over all user directories and delete the cookie file from each one -	LLDirIterator dir_iter(base_dir, "*_*"); -	while (dir_iter.next(filename)) -	{ -		target = gDirUtilp->add(base_dir, filename); -		gDirUtilp->append(target, "browser_profile"); -		gDirUtilp->append(target, "cookies"); -		LL_DEBUGS() << "target = " << target << LL_ENDL; -		if(LLFile::isfile(target)) -		{ -			LLFile::remove(target); -		} - -		// Other accounts may have new-style cookie files too -- delete them as well -		target = gDirUtilp->add(base_dir, filename); -		gDirUtilp->append(target, PLUGIN_COOKIE_FILE_NAME); -		LL_DEBUGS() << "target = " << target << LL_ENDL; -		if(LLFile::isfile(target)) -		{ -			LLFile::remove(target); -		} -	} - -	// If we have an OpenID cookie, re-add it to the cookie store. -	setOpenIDCookie(std::string());  }  ///////////////////////////////////////////////////////////////////////////////////////// @@ -1145,7 +1077,7 @@ void LLViewerMedia::setCookiesEnabled(bool enabled)  		LLViewerMediaImpl* pimpl = *iter;  		if(pimpl->mMediaSource)  		{ -			pimpl->mMediaSource->enable_cookies(enabled); +			pimpl->mMediaSource->cookies_enabled(enabled);  		}  	}  } @@ -1170,127 +1102,7 @@ void LLViewerMedia::setProxyConfig(bool enable, const std::string &host, int por  /////////////////////////////////////////////////////////////////////////////////////////  // static  ///////////////////////////////////////////////////////////////////////////////////////// -// static -LLPluginCookieStore *LLViewerMedia::getCookieStore() -{ -	if(sCookieStore == NULL) -	{ -		sCookieStore = new LLPluginCookieStore; -	} - -	return sCookieStore; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// static -void LLViewerMedia::loadCookieFile() -{ -	// build filename for each user -	std::string resolved_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PLUGIN_COOKIE_FILE_NAME); - -	if (resolved_filename.empty()) -	{ -		LL_INFOS() << "can't get path to plugin cookie file - probably not logged in yet." << LL_ENDL; -		return; -	} - -	// open the file for reading -	llifstream file(resolved_filename.c_str()); -	if (!file.is_open()) -	{ -		LL_WARNS() << "can't load plugin cookies from file \"" << PLUGIN_COOKIE_FILE_NAME << "\"" << LL_ENDL; -		return; -	} - -	getCookieStore()->readAllCookies(file, true); - -	file.close(); - -	// send the clear_cookies message to all loaded plugins -	impl_list::iterator iter = sViewerMediaImplList.begin(); -	impl_list::iterator end = sViewerMediaImplList.end(); -	for (; iter != end; iter++) -	{ -		LLViewerMediaImpl* pimpl = *iter; -		if(pimpl->mMediaSource) -		{ -			pimpl->mMediaSource->clear_cookies(); -		} -	} - -	// If we have an OpenID cookie, re-add it to the cookie store. -	setOpenIDCookie(std::string()); -} - - -///////////////////////////////////////////////////////////////////////////////////////// -// static -void LLViewerMedia::saveCookieFile() -{ -	// build filename for each user -	std::string resolved_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PLUGIN_COOKIE_FILE_NAME); - -	if (resolved_filename.empty()) -	{ -		LL_INFOS() << "can't get path to plugin cookie file - probably not logged in yet." << LL_ENDL; -		return; -	} - -	// open a file for writing -	llofstream file(resolved_filename.c_str()); -	if (!file.is_open()) -	{ -		LL_WARNS() << "can't open plugin cookie file \"" << PLUGIN_COOKIE_FILE_NAME << "\" for writing" << LL_ENDL; -		return; -	} - -	getCookieStore()->writePersistentCookies(file); - -	file.close(); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// static -void LLViewerMedia::addCookie(const std::string &name, const std::string &value, const std::string &domain, const LLDate &expires, const std::string &path, bool secure) -{ -	std::stringstream cookie; - -	cookie << name << "=" << LLPluginCookieStore::quoteString(value); - -	if(expires.notNull()) -	{ -		cookie << "; expires=" << expires.asRFC1123(); -	} - -	cookie << "; domain=" << domain; - -	cookie << "; path=" << path; - -	if(secure) -	{ -		cookie << "; secure"; -	} - -	getCookieStore()->setCookies(cookie.str()); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// static -void LLViewerMedia::addSessionCookie(const std::string &name, const std::string &value, const std::string &domain, const std::string &path, bool secure) -{ -	// A session cookie just has a NULL date. -	addCookie(name, value, domain, LLDate(), path, secure); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// static -void LLViewerMedia::removeCookie(const std::string &name, const std::string &domain, const std::string &path ) -{ -	// To remove a cookie, add one with the same name, domain, and path that expires in the past. - -	addCookie(name, "", domain, LLDate(LLDate::now().secondsSinceEpoch() - 1.0), path); -} - +//// static  LLSD LLViewerMedia::getHeaders()  { @@ -1395,8 +1207,6 @@ void LLViewerMedia::getOpenIDCookieCoro(std::string url)          hostEnd = authority.size();      } -    getCookieStore()->setCookiesFromHost(sOpenIDCookie, authority.substr(hostStart, hostEnd - hostStart)); -  	if (url.length())  	{  		LLMediaCtrl* media_instance = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("destination_guide_contents"); @@ -1434,7 +1244,6 @@ void LLViewerMedia::getOpenIDCookieCoro(std::string url)      httpHeaders->append(HTTP_OUT_HEADER_COOKIE, sOpenIDCookie);      httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, getCurrentUserAgent()); -      LL_DEBUGS("MediaAuth") << "Requesting " << url << LL_ENDL;      LL_DEBUGS("MediaAuth") << "sOpenIDCookie = [" << sOpenIDCookie << "]" << LL_ENDL; @@ -1459,13 +1268,9 @@ void LLViewerMedia::getOpenIDCookieCoro(std::string url)      const std::string& cookie = resultHeaders[HTTP_IN_HEADER_SET_COOKIE].asStringRef();      LL_DEBUGS("MediaAuth") << "cookie = " << cookie << LL_ENDL; -    // *TODO: What about bad status codes?  Does this destroy previous cookies? -    LLViewerMedia::getCookieStore()->setCookiesFromHost(cookie, hostAuth); -      // Set cookie for snapshot publishing.      std::string authCookie = cookie.substr(0, cookie.find(";")); // strip path      LLWebProfile::setAuthCookie(authCookie); -  }  ///////////////////////////////////////////////////////////////////////////////////////// @@ -1660,12 +1465,6 @@ void LLViewerMedia::cleanupClass()  		delete sSpareBrowserMediaSource;  		sSpareBrowserMediaSource = NULL;  	} - -	if (sCookieStore != NULL) -	{ -		delete sCookieStore; -		sCookieStore = NULL; -	}  }  ////////////////////////////////////////////////////////////////////////////////////////// @@ -1898,6 +1697,8 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_  		std::string user_data_path_cookies = gDirUtilp->getOSUserAppDir();  		user_data_path_cookies += gDirUtilp->getDirDelimiter(); +		std::string user_data_path_cef_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "cef_log.txt"); +  		// Fix for EXT-5960 - make browser profile specific to user (cache, cookies etc.)  		// If the linden username returned is blank, that can only mean we are  		// at the login page displaying login Web page or Web browser test via Develop menu. @@ -1906,7 +1707,6 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_  		std::string linden_user_dir = gDirUtilp->getLindenUserDir();  		if ( ! linden_user_dir.empty() )  		{ -			// gDirUtilp->getLindenUserDir() is whole path, not just Linden name  			user_data_path_cookies = linden_user_dir;  			user_data_path_cookies += gDirUtilp->getDirDelimiter();  		}; @@ -1927,13 +1727,13 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_  		{  			media_source = new LLPluginClassMedia(owner);  			media_source->setSize(default_width, default_height); -			media_source->setUserDataPath(user_data_path_cache, user_data_path_cookies); +			media_source->setUserDataPath(user_data_path_cache, user_data_path_cookies, user_data_path_cef_log);  			media_source->setLanguageCode(LLUI::getLanguage());  			media_source->setZoomFactor(zoom_factor);  			// collect 'cookies enabled' setting from prefs and send to embedded browser  			bool cookies_enabled = gSavedSettings.getBOOL( "CookiesEnabled" ); -			media_source->enable_cookies( cookies_enabled || clean_browser); +			media_source->cookies_enabled( cookies_enabled || clean_browser);  			// collect 'plugins enabled' setting from prefs and send to embedded browser  			bool plugins_enabled = gSavedSettings.getBOOL( "BrowserPluginsEnabled" ); @@ -2040,17 +1840,6 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type)  			media_source->clear_cache();  		} -		// TODO: Only send cookies to plugins that need them -		//  Ideally, the plugin should tell us whether it handles cookies or not -- either via the init response or through a separate message. -		//  Due to the ordering of messages, it's possible we wouldn't get that information back in time to send cookies before sending a navigate message, -		//  which could cause odd race conditions. -		std::string all_cookies = LLViewerMedia::getCookieStore()->getAllCookies(); -		LL_DEBUGS() << "setting cookies: " << all_cookies << LL_ENDL; -		if(!all_cookies.empty()) -		{ -			media_source->set_cookies(all_cookies); -		} -  		mMediaSource = media_source;  		mMediaSource->setDeleteOK(false) ;  		updateVolume(); @@ -2992,14 +2781,10 @@ void LLViewerMediaImpl::update()  		updateVolume();  		// TODO: this is updated every frame - is this bad? -		updateJavascriptObject(); - -		// If we didn't just create the impl, it may need to get cookie updates. -		if(!sUpdatedCookies.empty()) -		{ -			// TODO: Only send cookies to plugins that need them -			mMediaSource->set_cookies(sUpdatedCookies); -		} +		// Removing this as part of the post viewer64 media update +		// Removed as not implemented in CEF embedded browser +		// See MAINT-8194 for a more fuller description +		// updateJavascriptObject();  	} @@ -3489,22 +3274,40 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla  		case LLViewerMediaObserver::MEDIA_EVENT_PICK_FILE_REQUEST:  		{ -			// Display a file picker -			std::string response; -  			LLFilePicker& picker = LLFilePicker::instance(); -			if (!picker.getOpenFile(LLFilePicker::FFLOAD_ALL)) +			std::vector<std::string> responses; + +			bool pick_multiple_files = plugin->getIsMultipleFilePick(); +			if (pick_multiple_files == false)  			{ -				// The user didn't pick a file -- the empty response string will indicate this. +				picker.getOpenFile(LLFilePicker::FFLOAD_ALL); + +				std::string filename = picker.getFirstFile(); +				responses.push_back(filename);  			} +			else +			{ +				if (picker.getMultipleOpenFiles()) +				{ +					std::string filename = picker.getFirstFile(); -			response = picker.getFirstFile(); +					responses.push_back(filename); -			plugin->sendPickFileResponse(response); +					while (!filename.empty()) +					{ +						filename = picker.getNextFile(); + +						if (!filename.empty()) +						{ +							responses.push_back(filename); +						} +					} +				} +			} +			plugin->sendPickFileResponse(responses);  		}  		break; -  		case LLViewerMediaObserver::MEDIA_EVENT_AUTH_REQUEST:  		{  			LLNotification::Params auth_request_params; @@ -3574,13 +3377,6 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla  ////////////////////////////////////////////////////////////////////////////////  // virtual -void LLViewerMediaImpl::handleCookieSet(LLPluginClassMedia* self, const std::string &cookie) -{ -	LLViewerMedia::getCookieStore()->setCookies(cookie); -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual  void  LLViewerMediaImpl::cut()  { diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index 0212bf88bf..6e18c4fecb 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -50,7 +50,6 @@ class LLViewerMediaTexture;  class LLMediaEntry;  class LLVOVolume;  class LLMimeDiscoveryResponder; -class LLPluginCookieStore;  typedef LLPointer<LLViewerMediaImpl> viewer_media_t;  /////////////////////////////////////////////////////////////////////////////// @@ -149,13 +148,6 @@ public:  	// Set the proxy config for all loaded plugins  	static void setProxyConfig(bool enable, const std::string &host, int port); -	static LLPluginCookieStore *getCookieStore(); -	static void loadCookieFile(); -	static void saveCookieFile(); -	static void addCookie(const std::string &name, const std::string &value, const std::string &domain, const LLDate &expires, const std::string &path = std::string("/"), bool secure = false ); -	static void addSessionCookie(const std::string &name, const std::string &value, const std::string &domain, const std::string &path = std::string("/"), bool secure = false ); -	static void removeCookie(const std::string &name, const std::string &domain, const std::string &path = std::string("/") ); -  	static void openIDSetup(const std::string &openid_url, const std::string &openid_token);  	static void openIDCookieResponse(const std::string& url, const std::string &cookie); @@ -178,7 +170,6 @@ private:      static void openIDSetupCoro(std::string openidUrl, std::string openidToken);      static void getOpenIDCookieCoro(std::string url); -	static LLPluginCookieStore *sCookieStore;  	static LLURL sOpenIDURL;  	static std::string sOpenIDCookie;  	static LLPluginClassMedia* sSpareBrowserMediaSource; @@ -337,7 +328,6 @@ public:  	// Inherited from LLPluginClassMediaOwner  	/*virtual*/ void handleMediaEvent(LLPluginClassMedia* plugin, LLPluginClassMediaOwner::EMediaEvent); -	/*virtual*/ void handleCookieSet(LLPluginClassMedia* self, const std::string &cookie);  	// LLEditMenuHandler overrides  	/*virtual*/ void	cut(); diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp index 06ce497510..81d4e30a7a 100644 --- a/indra/newview/llwebprofile.cpp +++ b/indra/newview/llwebprofile.cpp @@ -31,7 +31,6 @@  // libs  #include "llbufferstream.h"  #include "llimagepng.h" -#include "llplugincookiestore.h"  #include "llsdserialize.h" diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml index 60f36770bb..71f4d81195 100644 --- a/indra/newview/skins/default/xui/en/floater_about.xml +++ b/indra/newview/skins/default/xui/en/floater_about.xml @@ -8,14 +8,14 @@   help_topic="floater_about"   save_rect="true"   title="ABOUT [CAPITALIZED_APP_NAME]" - width="470"> + width="500">    <tab_container      follows="all"       top="25"      left="10"      height="405"  -    width="450"  +    width="480"       name="about_tab"      tab_position="top">      <panel @@ -33,7 +33,7 @@         max_length="65536"         name="support_editor"         top="5" -       width="435" +       width="465"         word_wrap="true" />        <button          follows="left|top"  @@ -56,7 +56,7 @@            left="5"            name="linden_intro"            top="10" -          width="435" +          width="465"            wrap="true">  Second Life is brought to you by the Lindens,   with open source contributions from: @@ -71,7 +71,7 @@ with open source contributions from:         max_length="65536"         name="contrib_names"         top_pad="10" -       width="435" +       width="465"         word_wrap="true">  Dummy Name replaced at run time        </text_editor> @@ -91,7 +91,7 @@ Dummy Name replaced at run time         max_length="65536"         name="licenses_editor"         top="5" -       width="435" +       width="465"         word_wrap="true">          3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion          APR Copyright (C) 2011 The Apache Software Foundation diff --git a/indra/newview/skins/default/xui/en/floater_web_content.xml b/indra/newview/skins/default/xui/en/floater_web_content.xml index fe9ffba6cd..9a097d933b 100644 --- a/indra/newview/skins/default/xui/en/floater_web_content.xml +++ b/indra/newview/skins/default/xui/en/floater_web_content.xml @@ -178,108 +178,7 @@          width="22">          <button.commit_callback            function="WebContent.TestURL" -          parameter="https://callum-linden.s3.amazonaws.com/ceftests.html"/> -      </button> - -      <button -        image_overlay="Video_URL_Off" -            image_disabled="PushButton_Disabled" -            image_disabled_selected="PushButton_Disabled" -            image_selected="PushButton_Selected" -            image_unselected="PushButton_Off" -        chrome="true" -        tool_tip="MPEG4 Video Test" -        enabled="true" -        follows="left|top" -        height="22" -        layout="topleft" -        left="27" -        name="VLC Plugin Test" -        top="0" -        width="22"> -        <button.commit_callback -          function="WebContent.TestURL" -          parameter="https://callum-linden.s3.amazonaws.com/sample_media/ss.mp4"/> -      </button> -      <button -        image_overlay="Video_URL_Off" -            image_disabled="PushButton_Disabled" -            image_disabled_selected="PushButton_Disabled" -            image_selected="PushButton_Selected" -            image_unselected="PushButton_Off" -        chrome="true" -        tool_tip="MKV Video Test" -        enabled="true" -        follows="left|top" -        height="22" -        layout="topleft" -        left="51" -        name="VLC Plugin Test" -        top="0" -        width="22"> -        <button.commit_callback -          function="WebContent.TestURL" -          parameter="https://callum-linden.s3.amazonaws.com/sample_media/jellyfish.mkv"/> -      </button> -      <button -        image_overlay="Video_URL_Off" -            image_disabled="PushButton_Disabled" -            image_disabled_selected="PushButton_Disabled" -            image_selected="PushButton_Selected" -            image_unselected="PushButton_Off" -        chrome="true" -        tool_tip="WebM Video Test" -        enabled="true" -        follows="left|top" -        height="22" -        layout="topleft" -        left="75" -        name="VLC Plugin Test" -        top="0" -        width="22"> -        <button.commit_callback -          function="WebContent.TestURL" -          parameter="https://callum-linden.s3.amazonaws.com/sample_media/jumprope.webm"/> -      </button> -      <button -        image_overlay="Video_URL_Off" -            image_disabled="PushButton_Disabled" -            image_disabled_selected="PushButton_Disabled" -            image_selected="PushButton_Selected" -            image_unselected="PushButton_Off" -        chrome="true" -        tool_tip="MP3 audio Test" -        enabled="true" -        follows="left|top" -        height="22" -        layout="topleft" -        left="99" -        name="VLC Plugin Test" -        top="0" -        width="22"> -        <button.commit_callback -          function="WebContent.TestURL" -          parameter="https://callum-linden.s3.amazonaws.com/alegria.mp3"/> -      </button> -      <button -        image_overlay="Video_URL_Off" -            image_disabled="PushButton_Disabled" -            image_disabled_selected="PushButton_Disabled" -            image_selected="PushButton_Selected" -            image_unselected="PushButton_Off" -        chrome="true" -        tool_tip="FLV Test" -        enabled="true" -        follows="left|top" -        height="22" -        layout="topleft" -        left="123" -        name="VLC Plugin Test" -        top="0" -        width="22"> -        <button.commit_callback -          function="WebContent.TestURL" -          parameter="https://callum-linden.s3.amazonaws.com/sample_media/vandal.flv"/> +          parameter="https://sl-viewer-media-system.s3.amazonaws.com/index.html"/>        </button>      </layout_panel>      <layout_panel diff --git a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml index 284688d4d1..2ec5cef640 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml @@ -19,7 +19,7 @@        follows="left|top"        height="23"        label="Clear History" -      tool_tip="Clear login image, last location, teleport history, web, and texture cache" +      tool_tip="Clear login image, last location, teleport history, web and texture cache"        layout="topleft"        left="30"        name="clear_cache" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml index 1d4cbca1a5..6732f4ff1c 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml @@ -106,38 +106,6 @@           width="300">      Web:    </text> - <!-- <radio_group -   control_name="UseExternalBrowser" -   draw_border="false" -   follows="top|left" -   height="40" -   layout="topleft" -   left_delta="50" -   name="use_external_browser" -   top_pad="-2" -   width="480"> -    <radio_item -      height="20" -      label="Use my browser (IE, Firefox, Safari)" -      layout="topleft" -      left_delta="0" -      name="external" -      value="true" -      top="0" -      tool_tip="Use the default system web browser for help, web links, etc. Not recommended if running full screen." -      width="480" /> -    <radio_item -      height="20" -      label="Use built-in browser" -      layout="topleft" -      left="0" -      name="internal" -      value="" -      tool_tip="Use the built-in web browser for help, web links, etc. This browser opens as a new window inside [APP_NAME]." -      top_delta="20" -      width="480" /> -  </radio_group> --> -    <radio_group     control_name="PreferredBrowserBehavior"     follows="left|top" @@ -149,7 +117,7 @@     width="480">      <radio_item        height="20" -      label="Use my browser (Chrome, Firefox, IE) for all links" +      label="Use the default system browser for all links"        layout="topleft"        left="0"        name="internal" @@ -159,17 +127,17 @@        width="480" />      <radio_item        height="20" -      label="Use built-in browser for Second Life links only" +      label="Use the built-in browser for Second Life links only"        layout="topleft"        left_delta="0"        name="external"        value="1"       -      tool_tip="Use the default system web browser for help, web links, etc. Builtin browser will be used only for LindenLab/SecondLife links." +      tool_tip="Use the default system web browser for help, web links, etc. The built-in browser will be used only for LindenLab/Second Life links."        top_delta="20"        width="480" />      <radio_item        height="20" -      label="Use built-in browser for all links" +      label="Use the built-in browser for all links"        layout="topleft"        left="0"        name="external_all" @@ -193,22 +161,6 @@      radio_style="false"      width="400"      top_pad="5"/> - -  <check_box -   top_delta="4" -   enabled="true" -   follows="left|top" -   height="14" -   initial_value="true" -   control_name="CookiesEnabled" -   label="Accept cookies" -   left_delta="0" -   mouse_opaque="true"  -   name="cookies_enabled" -   radio_style="false" -   width="400" -   top_pad="5"/> -      <check_box      top_delta="4"      enabled="true" | 
