diff --git a/core/src/main/scala/org/apache/spark/SparkContext.scala b/core/src/main/scala/org/apache/spark/SparkContext.scala index 7257371256d9..c6cb5cb5e19a 100644 --- a/core/src/main/scala/org/apache/spark/SparkContext.scala +++ b/core/src/main/scala/org/apache/spark/SparkContext.scala @@ -592,9 +592,8 @@ class SparkContext(config: SparkConf) extends Logging { _env.blockManager.blockStoreClient.setAppAttemptId(attemptId) } if (_conf.get(UI_REVERSE_PROXY)) { - val proxyUrl = _conf.get(UI_REVERSE_PROXY_URL.key, "").stripSuffix("/") + - "/proxy/" + _applicationId - System.setProperty("spark.ui.proxyBase", proxyUrl) + val proxyUrl = _conf.get(UI_REVERSE_PROXY_URL).getOrElse("").stripSuffix("/") + System.setProperty("spark.ui.proxyBase", proxyUrl + "/proxy/" + _applicationId) } _ui.foreach(_.setAppId(_applicationId)) _env.blockManager.initialize(_applicationId) diff --git a/core/src/main/scala/org/apache/spark/internal/config/UI.scala b/core/src/main/scala/org/apache/spark/internal/config/UI.scala index 1790e97b35ae..464034b8fcd6 100644 --- a/core/src/main/scala/org/apache/spark/internal/config/UI.scala +++ b/core/src/main/scala/org/apache/spark/internal/config/UI.scala @@ -79,6 +79,11 @@ private[spark] object UI { "reach your proxy.") .version("2.1.0") .stringConf + .checkValue ({ s => + val words = s.split("/") + !words.contains("proxy") && !words.contains("history") }, + "Cannot use the keyword 'proxy' or 'history' in reverse proxy URL. Spark UI relies on both " + + "keywords for getting REST API endpoints from URIs.") .createOptional val UI_KILL_ENABLED = ConfigBuilder("spark.ui.killEnabled") diff --git a/core/src/test/scala/org/apache/spark/SparkContextSuite.scala b/core/src/test/scala/org/apache/spark/SparkContextSuite.scala index 8671180b3ca5..c64a43719116 100644 --- a/core/src/test/scala/org/apache/spark/SparkContextSuite.scala +++ b/core/src/test/scala/org/apache/spark/SparkContextSuite.scala @@ -1343,6 +1343,17 @@ class SparkContextSuite extends SparkFunSuite with LocalSparkContext with Eventu assert(env.blockManager.blockStoreClient.getAppAttemptId.equals("1")) } + test("SPARK-34659: check invalid UI_REVERSE_PROXY_URL") { + val reverseProxyUrl = "http://proxyhost:8080/path/proxy/spark" + val conf = new SparkConf().setAppName("testAppAttemptId") + .setMaster("pushbasedshuffleclustermanager") + conf.set(UI_REVERSE_PROXY, true) + conf.set(UI_REVERSE_PROXY_URL, reverseProxyUrl) + val msg = intercept[java.lang.IllegalArgumentException] { + new SparkContext(conf) + }.getMessage + assert(msg.contains("Cannot use the keyword 'proxy' or 'history' in reverse proxy URL")) + } } object SparkContextSuite { diff --git a/docs/configuration.md b/docs/configuration.md index 4fa37792a335..c0f3de86f984 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -1324,7 +1324,9 @@ Apart from these, the following properties are also available, and may be useful This setting affects all the workers and application UIs running in the cluster and must be set identically on all the workers, drivers and masters. In is only effective when spark.ui.reverseProxy is turned on. This setting is not needed when the Spark - master web UI is directly reachable. + master web UI is directly reachable.
+ Note that the value of the setting can't contain the keyword `proxy` or `history` after split by "/". Spark UI relies on both keywords for getting REST API endpoints from URIs. + 2.1.0