YARN-4820. ResourceManager web redirects in HA mode drops query parameters. Contributed by Varun Vasudev.

(cherry picked from commit 19b645c938)
This commit is contained in:
Junping Du 2016-03-23 19:34:30 -07:00
parent daf24eeb6b
commit c722262c75
2 changed files with 35 additions and 12 deletions

View File

@ -273,8 +273,8 @@ public void testRMWebAppRedirect() throws YarnException,
redirectURL = getRedirectURL(rm2Url + "/metrics");
assertEquals(redirectURL,rm1Url + "/metrics");
redirectURL = getRedirectURL(rm2Url + "/jmx");
assertEquals(redirectURL,rm1Url + "/jmx");
redirectURL = getRedirectURL(rm2Url + "/jmx?param1=value1+x&param2=y");
assertEquals(rm1Url + "/jmx?param1=value1+x&param2=y", redirectURL);
// standby RM links /conf, /stacks, /logLevel, /static, /logs,
// /cluster/cluster as well as webService
@ -327,8 +327,9 @@ static String getRedirectURL(String url) {
// do not automatically follow the redirection
// otherwise we get too many redirections exception
conn.setInstanceFollowRedirects(false);
if(conn.getResponseCode() == HttpServletResponse.SC_TEMPORARY_REDIRECT)
if(conn.getResponseCode() == HttpServletResponse.SC_TEMPORARY_REDIRECT) {
redirectUrl = conn.getHeaderField("Location");
}
} catch (Exception e) {
// throw new RuntimeException(e);
}

View File

@ -25,6 +25,8 @@
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Random;
import java.util.Set;
@ -48,6 +50,8 @@
import org.apache.hadoop.yarn.util.ConverterUtils;
import org.apache.hadoop.yarn.webapp.YarnWebParams;
import org.apache.hadoop.yarn.webapp.util.WebAppUtils;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -106,22 +110,40 @@ public void doFilter(HttpServletRequest request,
HttpServletResponse response, FilterChain chain) throws IOException,
ServletException {
response.setCharacterEncoding("UTF-8");
String uri = HtmlQuoting.quoteHtmlChars(request.getRequestURI());
String htmlEscapedUri = HtmlQuoting.quoteHtmlChars(request.getRequestURI());
if (uri == null) {
uri = "/";
if (htmlEscapedUri == null) {
htmlEscapedUri = "/";
}
String uriWithQueryString = htmlEscapedUri;
String htmlEscapedUriWithQueryString = htmlEscapedUri;
String queryString = request.getQueryString();
if (queryString != null && !queryString.isEmpty()) {
String reqEncoding = request.getCharacterEncoding();
if (reqEncoding == null || reqEncoding.isEmpty()) {
reqEncoding = "ISO-8859-1";
}
Charset encoding = Charset.forName(reqEncoding);
List<NameValuePair> params = URLEncodedUtils.parse(queryString, encoding);
String urlEncodedQueryString = URLEncodedUtils.format(params, encoding);
uriWithQueryString += "?" + urlEncodedQueryString;
htmlEscapedUriWithQueryString = HtmlQuoting.quoteHtmlChars(
request.getRequestURI() + "?" + urlEncodedQueryString);
}
RMWebApp rmWebApp = injector.getInstance(RMWebApp.class);
rmWebApp.checkIfStandbyRM();
if (rmWebApp.isStandby()
&& shouldRedirect(rmWebApp, uri)) {
&& shouldRedirect(rmWebApp, htmlEscapedUri)) {
String redirectPath = rmWebApp.getRedirectPath();
if (redirectPath != null && !redirectPath.isEmpty()) {
redirectPath += uri;
String redirectMsg =
"This is standby RM. The redirect url is: " + redirectPath;
redirectPath += uriWithQueryString;
String redirectMsg = "This is standby RM. The redirect url is: "
+ htmlEscapedUriWithQueryString;
PrintWriter out = response.getWriter();
out.println(redirectMsg);
response.setHeader("Location", redirectPath);
@ -142,7 +164,7 @@ && shouldRedirect(rmWebApp, uri)) {
int next = calculateExponentialTime(retryInterval);
String redirectUrl =
appendOrReplaceParamter(path + uri,
appendOrReplaceParamter(path + uriWithQueryString,
YarnWebParams.NEXT_REFRESH_INTERVAL + "=" + (retryInterval + 1));
if (redirectUrl == null || next > MAX_SLEEP_TIME) {
doRetry = false;
@ -161,7 +183,7 @@ && shouldRedirect(rmWebApp, uri)) {
}
return;
} else if (ahsEnabled) {
String ahsRedirectUrl = ahsRedirectPath(uri, rmWebApp);
String ahsRedirectUrl = ahsRedirectPath(uriWithQueryString, rmWebApp);
if(ahsRedirectUrl != null) {
response.setHeader("Location", ahsRedirectUrl);
response.setStatus(HttpServletResponse.SC_TEMPORARY_REDIRECT);