From 454c7f4543688126b2fa5c0560710f5a1733702e Mon Sep 17 00:00:00 2001
From: Callum Linden <callum@lindenlab.com>
Date: Tue, 5 Oct 2021 14:37:48 -0700
Subject: [PATCH] Fix: SL-12320 The Viewer functionality is broken with an
 in-viewer enabled proxy

---
 autobuild.xml                                 |  14 +--
 indra/media_plugins/cef/media_plugin_cef.cpp  | 104 +++++++++++-------
 indra/newview/llviewermedia.cpp               |   6 +-
 .../xui/en/panel_preferences_setup.xml        |  32 +++---
 4 files changed, 90 insertions(+), 66 deletions(-)

diff --git a/autobuild.xml b/autobuild.xml
index 4768bd25c67..efa04d0f639 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -580,9 +580,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>49fff41e17e06cdf9eb0c737d20df52f</string>
+              <string>6b5210f0f529b294e13e1a5ea4271363</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/83411/779825/dullahan-1.12.2.202106220202_91.1.21_g9dd45fe_chromium-91.0.4472.114-darwin64-560751.tar.bz2</string>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/88757/812363/dullahan-1.12.3.202110051826_91.1.21_g9dd45fe_chromium-91.0.4472.114-darwin64-564501.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -592,9 +592,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>f51f324d50a2461cda273e84fa65e0ad</string>
+              <string>eb9b46761122a1746aff98de1115cc39</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/83413/779836/dullahan-1.12.2.202106220213_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows-560751.tar.bz2</string>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/88756/812368/dullahan-1.12.3.202110051827_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows-564501.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -604,16 +604,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>d3df46f6592715c75df2bf520c1ad68b</string>
+              <string>0c8102b5375402704ea8302827e8182b</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/83412/779840/dullahan-1.12.2.202106220213_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows64-560751.tar.bz2</string>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/88754/812351/dullahan-1.12.3.202110051815_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows64-564501.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.12.2.202106220213_91.1.21_g9dd45fe_chromium-91.0.4472.114</string>
+        <string>1.12.3.202110051815_91.1.21_g9dd45fe_chromium-91.0.4472.114</string>
       </map>
       <key>elfio</key>
       <map>
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 8465285d2b7..567bab2acf9 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -89,6 +89,9 @@ class MediaPluginCEF :
 	bool mCookiesEnabled;
 	bool mPluginsEnabled;
 	bool mJavascriptEnabled;
+    bool mProxyEnabled;
+    std::string mProxyHost;
+    int mProxyPort;
 	bool mDisableGPU;
 	bool mDisableNetworkService;
 	bool mUseMockKeyChain;
@@ -124,6 +127,9 @@ MediaPluginBase(host_send_func, host_user_data)
 	mCookiesEnabled = true;
 	mPluginsEnabled = false;
 	mJavascriptEnabled = true;
+    mProxyEnabled = false;
+    mProxyHost = "";
+    mProxyPort = 0;
 	mDisableGPU = false;
 	mDisableNetworkService = true;
 	mUseMockKeyChain = true;
@@ -513,50 +519,58 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 		}
 		else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
 		{
-			if (message_name == "init")
-			{
-				// event callbacks from Dullahan
-				mCEFLib->setOnPageChangedCallback(std::bind(&MediaPluginCEF::onPageChangedCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
-				mCEFLib->setOnCustomSchemeURLCallback(std::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, std::placeholders::_1));
-				mCEFLib->setOnConsoleMessageCallback(std::bind(&MediaPluginCEF::onConsoleMessageCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
-				mCEFLib->setOnStatusMessageCallback(std::bind(&MediaPluginCEF::onStatusMessageCallback, this, std::placeholders::_1));
-				mCEFLib->setOnTitleChangeCallback(std::bind(&MediaPluginCEF::onTitleChangeCallback, this, std::placeholders::_1));
-				mCEFLib->setOnTooltipCallback(std::bind(&MediaPluginCEF::onTooltipCallback, 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->setOnOpenPopupCallback(std::bind(&MediaPluginCEF::onOpenPopupCallback, this, std::placeholders::_1, std::placeholders::_2));
-				mCEFLib->setOnHTTPAuthCallback(std::bind(&MediaPluginCEF::onHTTPAuthCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
-				mCEFLib->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));
-				mCEFLib->setOnJSDialogCallback(std::bind(&MediaPluginCEF::onJSDialogCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
-				mCEFLib->setOnJSBeforeUnloadCallback(std::bind(&MediaPluginCEF::onJSBeforeUnloadCallback, this));
-				
-				dullahan::dullahan_settings settings;
+            if (message_name == "init")
+            {
+                // event callbacks from Dullahan
+                mCEFLib->setOnPageChangedCallback(std::bind(&MediaPluginCEF::onPageChangedCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
+                mCEFLib->setOnCustomSchemeURLCallback(std::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, std::placeholders::_1));
+                mCEFLib->setOnConsoleMessageCallback(std::bind(&MediaPluginCEF::onConsoleMessageCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
+                mCEFLib->setOnStatusMessageCallback(std::bind(&MediaPluginCEF::onStatusMessageCallback, this, std::placeholders::_1));
+                mCEFLib->setOnTitleChangeCallback(std::bind(&MediaPluginCEF::onTitleChangeCallback, this, std::placeholders::_1));
+                mCEFLib->setOnTooltipCallback(std::bind(&MediaPluginCEF::onTooltipCallback, 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->setOnOpenPopupCallback(std::bind(&MediaPluginCEF::onOpenPopupCallback, this, std::placeholders::_1, std::placeholders::_2));
+                mCEFLib->setOnHTTPAuthCallback(std::bind(&MediaPluginCEF::onHTTPAuthCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
+                mCEFLib->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));
+                mCEFLib->setOnJSDialogCallback(std::bind(&MediaPluginCEF::onJSDialogCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
+                mCEFLib->setOnJSBeforeUnloadCallback(std::bind(&MediaPluginCEF::onJSBeforeUnloadCallback, this));
+
+                dullahan::dullahan_settings settings;
 #if LL_WINDOWS
-				// As of CEF version 83+, for Windows versions, we need to tell CEF 
-				// where the host helper process is since this DLL is not in the same
-				// dir as the executable that loaded it (SLPlugin.exe). The code in 
-				// Dullahan that tried to figure out the location automatically uses 
-				// the location of the exe which isn't helpful so we tell it explicitly.
-				char cur_dir_str[MAX_PATH];
-				GetCurrentDirectoryA(MAX_PATH, cur_dir_str);
-				settings.host_process_path = std::string(cur_dir_str);
+                // As of CEF version 83+, for Windows versions, we need to tell CEF 
+                // where the host helper process is since this DLL is not in the same
+                // dir as the executable that loaded it (SLPlugin.exe). The code in 
+                // Dullahan that tried to figure out the location automatically uses 
+                // the location of the exe which isn't helpful so we tell it explicitly.
+                char cur_dir_str[MAX_PATH];
+                GetCurrentDirectoryA(MAX_PATH, cur_dir_str);
+                settings.host_process_path = std::string(cur_dir_str);
 #endif
-				settings.accept_language_list = mHostLanguage;
-
-				// SL-15560: Product team overruled my change to set the default
-				// embedded background color to match the floater background
-				// and set it to white
-				settings.background_color = 0xffffffff;	// white 
-
-				settings.cache_enabled = true;
-				settings.root_cache_path = mRootCachePath;
-				settings.cache_path = mCachePath;
-				settings.context_cache_path = mContextCachePath;
-				settings.cookies_enabled = mCookiesEnabled;
+                settings.accept_language_list = mHostLanguage;
+
+                // SL-15560: Product team overruled my change to set the default
+                // embedded background color to match the floater background
+                // and set it to white
+                settings.background_color = 0xffffffff;	// white 
+
+                settings.cache_enabled = true;
+                settings.root_cache_path = mRootCachePath;
+                settings.cache_path = mCachePath;
+                settings.context_cache_path = mContextCachePath;
+                settings.cookies_enabled = mCookiesEnabled;
+
+                // configure proxy argument if enabled and valid
+                if (mProxyEnabled && mProxyHost.length())
+                {
+                    std::ostringstream proxy_url;
+                    proxy_url << mProxyHost << ":" << mProxyPort;
+                    settings.proxy_host_port = proxy_url.str();
+                }
 				settings.disable_gpu = mDisableGPU;
 #if LL_DARWIN
 				settings.disable_network_service = mDisableNetworkService;
@@ -883,6 +897,12 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 			{
 				mDisableGPU = message_in.getValueBoolean("disable");
 			}
+            else if (message_name == "proxy_setup")
+            {
+                mProxyEnabled = message_in.getValueBoolean("enable");
+                mProxyHost = message_in.getValue("host");
+                mProxyPort = message_in.getValueS32("port");
+            }
 		}
         else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME)
         {
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index d35dbda907d..5de7744972e 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -1759,6 +1759,10 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
 			// need to set agent string here before instance created
 			media_source->setBrowserUserAgent(LLViewerMedia::getInstance()->getCurrentUserAgent());
 
+            // configure and pass proxy setup based on debug settings that are 
+            // configured by UI in prefs -> setup
+            media_source->proxy_setup(gSavedSettings.getBOOL("BrowserProxyEnabled"), gSavedSettings.getString("BrowserProxyAddress"), gSavedSettings.getS32("BrowserProxyPort"));
+
 			media_source->setTarget(target);
 
 			const std::string plugin_dir = gDirUtilp->getLLPluginDir();
@@ -1842,8 +1846,6 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type)
 		std::string ca_path = gDirUtilp->getCAFile();
 		media_source->addCertificateFilePath( ca_path );
 
-		media_source->proxy_setup(gSavedSettings.getBOOL("BrowserProxyEnabled"), gSavedSettings.getString("BrowserProxyAddress"), gSavedSettings.getS32("BrowserProxyPort"));
-
 		if(mClearCache)
 		{
 			mClearCache = false;
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 dff6f6e6000..5e41ba4ae19 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
@@ -227,23 +227,25 @@
      height="10"
      layout="topleft"
      left="30"
-     name="Proxy Settings 1"
-     mouse_opaque="false"
-     top_pad="10"
-     width="300">
-    Proxy Settings:
-  </text>
-  <text
-     type="string"
-     length="1"
-     follows="left|top"
-     height="10"
-     layout="topleft"
-     left="80"
-     name="Proxy Settings 2"
+     name="Proxy Settings:"
      mouse_opaque="false"
      top_pad="5"
      width="300">
-    Your system's existing proxy settings will be used
+    Proxy Settings:
   </text>
+  <button
+	label="Adjust proxy settings"
+    follows="left|top"
+    height="23"
+	width="140"
+    label_selected="Browse"
+    layout="topleft"
+    left_delta="50"
+    name="set_proxy"
+    top_pad="5"
+    >
+    <button.commit_callback
+		  function="Pref.Proxy" />
+  </button>
 </panel>
+
-- 
GitLab