Skip to content

Commit 491b47a

Browse files
jerryshaoMarcelo Vanzin
authored andcommitted
[SPARK-19750][UI][BRANCH-2.1] Fix redirect issue from http to https
## What changes were proposed in this pull request? If spark ui port (4040) is not set, it will choose port number 0, this will make https port to also choose 0. And in Spark 2.1 code, it will use this https port (0) to do redirect, so when redirect triggered, it will point to a wrong url: like: ``` /tmp/temp$ wget http://172.27.25.134:55015 --2017-02-23 12:13:54-- http://172.27.25.134:55015/ Connecting to 172.27.25.134:55015... connected. HTTP request sent, awaiting response... 302 Found Location: https://172.27.25.134:0/ [following] --2017-02-23 12:13:54-- https://172.27.25.134:0/ Connecting to 172.27.25.134:0... failed: Can't assign requested address. Retrying. --2017-02-23 12:13:55-- (try: 2) https://172.27.25.134:0/ Connecting to 172.27.25.134:0... failed: Can't assign requested address. Retrying. --2017-02-23 12:13:57-- (try: 3) https://172.27.25.134:0/ Connecting to 172.27.25.134:0... failed: Can't assign requested address. Retrying. --2017-02-23 12:14:00-- (try: 4) https://172.27.25.134:0/ Connecting to 172.27.25.134:0... failed: Can't assign requested address. Retrying. ``` So instead of using 0 to do redirect, we should pick a bound port instead. This issue only exists in Spark 2.1-, and can be reproduced in yarn cluster mode. ## How was this patch tested? Current redirect UT doesn't verify this issue, so extend current UT to do correct verification. Author: jerryshao <sshao@hortonworks.com> Closes #17083 from jerryshao/SPARK-19750. (cherry picked from commit 3a7591a) Signed-off-by: Marcelo Vanzin <vanzin@cloudera.com>
1 parent e30fe1c commit 491b47a

3 files changed

Lines changed: 30 additions & 9 deletions

File tree

core/src/main/scala/org/apache/spark/TestUtils.scala

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import java.util.Arrays
2727
import java.util.concurrent.{CountDownLatch, TimeUnit}
2828
import java.util.jar.{JarEntry, JarOutputStream}
2929
import javax.net.ssl._
30+
import javax.servlet.http.HttpServletResponse
3031
import javax.tools.{JavaFileObject, SimpleJavaFileObject, ToolProvider}
3132

3233
import scala.collection.JavaConverters._
@@ -186,12 +187,12 @@ private[spark] object TestUtils {
186187
}
187188

188189
/**
189-
* Returns the response code from an HTTP(S) URL.
190+
* Returns the response code and url (if redirected) from an HTTP(S) URL.
190191
*/
191-
def httpResponseCode(
192+
def httpResponseCodeAndURL(
192193
url: URL,
193194
method: String = "GET",
194-
headers: Seq[(String, String)] = Nil): Int = {
195+
headers: Seq[(String, String)] = Nil): (Int, Option[String]) = {
195196
val connection = url.openConnection().asInstanceOf[HttpURLConnection]
196197
connection.setRequestMethod(method)
197198
headers.foreach { case (k, v) => connection.setRequestProperty(k, v) }
@@ -210,16 +211,30 @@ private[spark] object TestUtils {
210211
sslCtx.init(null, Array(trustManager), new SecureRandom())
211212
connection.asInstanceOf[HttpsURLConnection].setSSLSocketFactory(sslCtx.getSocketFactory())
212213
connection.asInstanceOf[HttpsURLConnection].setHostnameVerifier(verifier)
214+
connection.setInstanceFollowRedirects(false)
213215
}
214216

215217
try {
216218
connection.connect()
217-
connection.getResponseCode()
219+
if (connection.getResponseCode == HttpServletResponse.SC_FOUND) {
220+
(connection.getResponseCode, Option(connection.getHeaderField("Location")))
221+
} else {
222+
(connection.getResponseCode(), None)
223+
}
218224
} finally {
219225
connection.disconnect()
220226
}
221227
}
222228

229+
/**
230+
* Returns the response code from an HTTP(S) URL.
231+
*/
232+
def httpResponseCode(
233+
url: URL,
234+
method: String = "GET",
235+
headers: Seq[(String, String)] = Nil): Int = {
236+
httpResponseCodeAndURL(url, method, headers)._1
237+
}
223238
}
224239

225240

core/src/main/scala/org/apache/spark/ui/JettyUtils.scala

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ private[spark] object JettyUtils extends Logging {
287287

288288
// redirect the HTTP requests to HTTPS port
289289
httpConnector.setName(REDIRECT_CONNECTOR_NAME)
290-
collection.addHandler(createRedirectHttpsHandler(securePort, scheme))
290+
collection.addHandler(createRedirectHttpsHandler(connector, scheme))
291291
Some(connector)
292292

293293
case None =>
@@ -335,7 +335,9 @@ private[spark] object JettyUtils extends Logging {
335335
server.getHandler().asInstanceOf[ContextHandlerCollection])
336336
}
337337

338-
private def createRedirectHttpsHandler(securePort: Int, scheme: String): ContextHandler = {
338+
private def createRedirectHttpsHandler(
339+
httpsConnector: ServerConnector,
340+
scheme: String): ContextHandler = {
339341
val redirectHandler: ContextHandler = new ContextHandler
340342
redirectHandler.setContextPath("/")
341343
redirectHandler.setVirtualHosts(Array("@" + REDIRECT_CONNECTOR_NAME))
@@ -348,8 +350,8 @@ private[spark] object JettyUtils extends Logging {
348350
if (baseRequest.isSecure) {
349351
return
350352
}
351-
val httpsURI = createRedirectURI(scheme, baseRequest.getServerName, securePort,
352-
baseRequest.getRequestURI, baseRequest.getQueryString)
353+
val httpsURI = createRedirectURI(scheme, baseRequest.getServerName,
354+
httpsConnector.getLocalPort, baseRequest.getRequestURI, baseRequest.getQueryString)
353355
response.setContentLength(0)
354356
response.encodeRedirectURL(httpsURI)
355357
response.sendRedirect(httpsURI)

core/src/test/scala/org/apache/spark/ui/UISuite.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,8 +232,12 @@ class UISuite extends SparkFunSuite {
232232
s"$scheme://localhost:$port/test1/root",
233233
s"$scheme://localhost:$port/test2/root")
234234
urls.foreach { url =>
235-
val rc = TestUtils.httpResponseCode(new URL(url))
235+
val (rc, redirectUrl) = TestUtils.httpResponseCodeAndURL(new URL(url))
236236
assert(rc === expected, s"Unexpected status $rc for $url")
237+
if (rc == HttpServletResponse.SC_FOUND) {
238+
assert(
239+
TestUtils.httpResponseCode(new URL(redirectUrl.get)) === HttpServletResponse.SC_OK)
240+
}
237241
}
238242
}
239243
} finally {

0 commit comments

Comments
 (0)