package org.ovirt.engine.core.utils.servlet; import java.io.IOException; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringUtils; import org.ovirt.engine.core.utils.EngineLocalConfig; /** * This servlet redirects a request to another URL which is defined as an init param. The key of the init param is * url. * <br /> * For instance: <br /> * <init-param> <br /> *   <param-name>url</param-name><br /> *   <param-value>/ovirt-engine/</param-value><br /> * </init-param> <br /> * The url param value can contain property expressions for expanding Engine property values in * form of %{PROP_NAME}. */ public class RedirectServlet extends HttpServlet { private static final long serialVersionUID = -1794616863361241804L; private static final String url404Default = EngineLocalConfig.getInstance().getEngineURI() + "/404.html"; private static final Pattern urlPattern = Pattern.compile( "((?<prefix>(\\w*://)([^/]*?@)?)?(?<host>(\\[[\\da-fA-F:]+\\])|([^/:]+)?))?(?<suffix>.*)" ); private static final String LOCALHOST_PLACEHOLDER = "@__LOCALHOST__@"; private static final String TARGET_URL = "targetUrl"; private static final String URL404 = "url404"; private static final Set<String> localHostNames = new HashSet<>(Arrays.asList( "localhost", "localhost.localdomain", "localhost4", "localhost4.localdomain", "localhost4.localdomain4", "localhost6", "localhost6.localdomain", "localhost6.localdomain6", "ip4-localhost", "ip4-loopback", "ip6-localhost", "ip6-loopback" )); private String targetUrl; private String url404; private String injectLocalHost(String url) { Matcher m = urlPattern.matcher(url); if (m.matches()) { String host = m.group("host"); if (host != null) { if (localHostNames.contains(host) || host.startsWith("127.") || host.equals("::1")) { url = String.format( "%s%s%s", m.group("prefix") != null ? m.group("prefix") : "", LOCALHOST_PLACEHOLDER, m.group("suffix") != null ? m.group("suffix") : "" ); } } } return url; } @Override public void init(ServletConfig config) throws ServletException { super.init(config); // we use %{x} convention to avoid conflict with jboss properties targetUrl = injectLocalHost(EngineLocalConfig.getInstance().expandString( config.getInitParameter(TARGET_URL).replaceAll("%\\{", "\\${"))); url404 = url404Default; if (StringUtils.isNotEmpty(config.getInitParameter(URL404))) { url404 = config.getInitParameter(URL404); } url404 = injectLocalHost(EngineLocalConfig.getInstance().expandString(url404.replaceAll("%\\{", "\\${"))); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String redirectUrl = targetUrl; if (StringUtils.isNotEmpty(redirectUrl)) { String pathInfo = request.getPathInfo(); if (StringUtils.isNotEmpty(pathInfo)) { redirectUrl += pathInfo; } String queryString = request.getQueryString(); if (StringUtils.isNotEmpty(queryString)) { if (redirectUrl.indexOf("?") == -1) { redirectUrl += "?"; } else { redirectUrl += "&"; } redirectUrl += queryString; } } else { redirectUrl = url404; } String localhost = request.getHeader("Host"); if (localhost != null) { if (localhost.charAt(0) == '[') { int n = localhost.indexOf("]"); if (n != -1) { localhost = localhost.substring(0, n+1); } } else { int n = localhost.indexOf(":"); if (n != -1) { localhost = localhost.substring(0, n); } } } else { localhost = EngineLocalConfig.getInstance().getHost(); } response.sendRedirect(redirectUrl.replace(LOCALHOST_PLACEHOLDER, localhost)); } }