/* * (C) Copyright 2006-2008 Nuxeo SA (http://nuxeo.com/) and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Contributors: * Nuxeo - initial API and implementation * * $Id$ */ package org.nuxeo.ecm.platform.web.common.vh; import static org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants.REQUESTED_URL; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuxeo.runtime.api.Framework; public class VirtualHostHelper { private static final int HTTP_PORT_NUMBER = 80; private static final int HTTPS_PORT_NUMBER = 443; private static final Log log = LogFactory.getLog(VirtualHostHelper.class); private static final String X_FORWARDED_HOST = "x-forwarded-host"; private static final String X_FORWARDED_PROTO = "x-forwarded-proto"; private static final String X_FORWARDED_PORT = "x-forwarded-port"; private static final String VH_HEADER = "nuxeo-virtual-host"; private static final String VH_PARAM = "nuxeo.virtual.host"; // Utility class. private VirtualHostHelper() { } private static HttpServletRequest getHttpServletRequest(ServletRequest request) { if (request instanceof HttpServletRequest) { return (HttpServletRequest) request; } return null; } /** * @return WebApp name : ie : nuxeo */ public static String getWebAppName(ServletRequest request) { return getContextPath(request).replace("/", ""); } /** * @return Server URL as : protocol://serverName:port/ */ public static String getServerURL(ServletRequest request) { return getServerURL(request, false); } private static String getServerUrl(String scheme, String serverName, int serverPort) { StringBuilder sbaseURL = new StringBuilder(); sbaseURL.append(scheme); sbaseURL.append("://"); sbaseURL.append(serverName); if (serverPort != 0) { if ("http".equals(scheme) && serverPort != HTTP_PORT_NUMBER || "https".equals(scheme) && serverPort != HTTPS_PORT_NUMBER) { sbaseURL.append(':'); sbaseURL.append(serverPort); } } sbaseURL.append('/'); return sbaseURL.toString(); } /** * @return Server URL as : protocol://serverName:port/ */ public static String getServerURL(ServletRequest request, boolean local) { String baseURL = null; HttpServletRequest httpRequest = getHttpServletRequest(request); if (httpRequest != null) { // Detect Nuxeo specific header for VH String nuxeoVH = httpRequest.getHeader(VH_HEADER); if (nuxeoVH == null) { nuxeoVH = Framework.getProperty(VH_PARAM); } if (!local && nuxeoVH != null && nuxeoVH.contains("http")) { baseURL = nuxeoVH; } else { // default values String serverName = httpRequest.getServerName(); int serverPort = httpRequest.getServerPort(); String scheme = httpRequest.getScheme(); if (!local) { String forwardedPort = httpRequest.getHeader(X_FORWARDED_PORT); if (forwardedPort != null) { try { serverPort = Integer.parseInt(forwardedPort); } catch (NumberFormatException e) { log.error("Unable to get forwarded port from header", e); } } String forwardedProto = httpRequest.getHeader(X_FORWARDED_PROTO); if (forwardedProto != null) { scheme = forwardedProto; } // Detect virtual hosting based in standard header String forwardedHost = httpRequest.getHeader(X_FORWARDED_HOST); if (forwardedHost != null) { if (forwardedHost.contains(":")) { serverName = forwardedHost.split(":")[0]; serverPort = Integer.valueOf(forwardedHost.split(":")[1]); } else { serverName = forwardedHost; serverPort = "https".equals(scheme) ? HTTPS_PORT_NUMBER : HTTP_PORT_NUMBER; } } } baseURL = getServerUrl(scheme, serverName, serverPort); } } if (baseURL == null) { log.error("Could not retrieve base url correctly"); log.debug("Could not retrieve base url correctly", new Throwable()); } return baseURL; } /** * @return base URL as protocol://serverName:port/webappName/ */ public static String getBaseURL(ServletRequest request) { String baseURL = null; String serverUrl = getServerURL(request, false); if (serverUrl != null) { String webAppName = getWebAppName(request); baseURL = StringUtils.isNotBlank(webAppName) ? serverUrl + webAppName + '/' : serverUrl; } return baseURL; } /** * Returns the context path of the application. Try to get it from the {@code ServletRequest} and then from the * {@code org.nuxeo.ecm.contextPath} system property. Fallback on default context path {@code /nuxeo}. */ public static String getContextPath(ServletRequest request) { HttpServletRequest httpRequest = getHttpServletRequest(request); String contextPath = null; if (httpRequest != null) { contextPath = httpRequest.getContextPath(); } return contextPath != null ? contextPath : getContextPathProperty(); } public static String getContextPathProperty() { return Framework.getProperty("org.nuxeo.ecm.contextPath", "/nuxeo"); } /** * Computes the url to be redirected when logging out * * @return redirect URL as protocol://serverName:port/webappName/... * @since 9.1 */ public static String getRedirectUrl(HttpServletRequest request) { String redirectURL = getBaseURL(request); if (request.getAttribute(REQUESTED_URL) != null) { redirectURL += request.getAttribute(REQUESTED_URL); } else if (request.getParameter(REQUESTED_URL) != null) { redirectURL += request.getParameter(REQUESTED_URL); } else { redirectURL = request.getRequestURL().toString(); String queryString = request.getQueryString(); if (queryString != null) { redirectURL += '?' + queryString; } } return redirectURL; } }