001/* 002 * (C) Copyright 2006-2008 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Nuxeo - initial API and implementation 018 * 019 * $Id$ 020 */ 021 022package org.nuxeo.ecm.platform.web.common.vh; 023 024import static org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants.REQUESTED_URL; 025 026import javax.servlet.ServletRequest; 027import javax.servlet.http.HttpServletRequest; 028 029import org.apache.commons.lang.StringUtils; 030import org.apache.commons.logging.Log; 031import org.apache.commons.logging.LogFactory; 032import org.nuxeo.runtime.api.Framework; 033 034public class VirtualHostHelper { 035 036 private static final int HTTP_PORT_NUMBER = 80; 037 038 private static final int HTTPS_PORT_NUMBER = 443; 039 040 private static final Log log = LogFactory.getLog(VirtualHostHelper.class); 041 042 private static final String X_FORWARDED_HOST = "x-forwarded-host"; 043 044 private static final String X_FORWARDED_PROTO = "x-forwarded-proto"; 045 046 private static final String X_FORWARDED_PORT = "x-forwarded-port"; 047 048 private static final String VH_HEADER = "nuxeo-virtual-host"; 049 050 private static final String VH_PARAM = "nuxeo.virtual.host"; 051 052 // Utility class. 053 private VirtualHostHelper() { 054 } 055 056 private static HttpServletRequest getHttpServletRequest(ServletRequest request) { 057 if (request instanceof HttpServletRequest) { 058 return (HttpServletRequest) request; 059 } 060 return null; 061 } 062 063 /** 064 * @return WebApp name : ie : nuxeo 065 */ 066 public static String getWebAppName(ServletRequest request) { 067 return getContextPath(request).replace("/", ""); 068 } 069 070 /** 071 * @return Server URL as : protocol://serverName:port/ 072 */ 073 public static String getServerURL(ServletRequest request) { 074 return getServerURL(request, false); 075 } 076 077 private static String getServerUrl(String scheme, String serverName, int serverPort) { 078 StringBuilder sbaseURL = new StringBuilder(); 079 sbaseURL.append(scheme); 080 sbaseURL.append("://"); 081 sbaseURL.append(serverName); 082 if (serverPort != 0) { 083 if ("http".equals(scheme) && serverPort != HTTP_PORT_NUMBER || "https".equals(scheme) 084 && serverPort != HTTPS_PORT_NUMBER) { 085 sbaseURL.append(':'); 086 sbaseURL.append(serverPort); 087 } 088 } 089 sbaseURL.append('/'); 090 return sbaseURL.toString(); 091 } 092 093 /** 094 * @return Server URL as : protocol://serverName:port/ 095 */ 096 public static String getServerURL(ServletRequest request, boolean local) { 097 String baseURL = null; 098 HttpServletRequest httpRequest = getHttpServletRequest(request); 099 if (httpRequest != null) { 100 // Detect Nuxeo specific header for VH 101 String nuxeoVH = httpRequest.getHeader(VH_HEADER); 102 if (nuxeoVH == null) { 103 nuxeoVH = Framework.getProperty(VH_PARAM); 104 } 105 if (!local && nuxeoVH != null && nuxeoVH.contains("http")) { 106 baseURL = nuxeoVH; 107 } else { 108 // default values 109 String serverName = httpRequest.getServerName(); 110 int serverPort = httpRequest.getServerPort(); 111 String scheme = httpRequest.getScheme(); 112 113 if (!local) { 114 String forwardedPort = httpRequest.getHeader(X_FORWARDED_PORT); 115 116 if (forwardedPort != null) { 117 try { 118 serverPort = Integer.parseInt(forwardedPort); 119 } catch (NumberFormatException e) { 120 log.error("Unable to get forwarded port from header", e); 121 } 122 } 123 124 String forwardedProto = httpRequest.getHeader(X_FORWARDED_PROTO); 125 if (forwardedProto != null) { 126 scheme = forwardedProto; 127 } 128 129 // Detect virtual hosting based in standard header 130 String forwardedHost = httpRequest.getHeader(X_FORWARDED_HOST); 131 if (forwardedHost != null) { 132 if (forwardedHost.contains(":")) { 133 serverName = forwardedHost.split(":")[0]; 134 serverPort = Integer.valueOf(forwardedHost.split(":")[1]); 135 } else { 136 serverName = forwardedHost; 137 serverPort = "https".equals(scheme) ? HTTPS_PORT_NUMBER : HTTP_PORT_NUMBER; 138 } 139 } 140 } 141 142 baseURL = getServerUrl(scheme, serverName, serverPort); 143 } 144 } 145 if (baseURL == null) { 146 log.error("Could not retrieve base url correctly"); 147 log.debug("Could not retrieve base url correctly", new Throwable()); 148 } 149 return baseURL; 150 } 151 152 /** 153 * @return base URL as protocol://serverName:port/webappName/ 154 */ 155 public static String getBaseURL(ServletRequest request) { 156 String baseURL = null; 157 String serverUrl = getServerURL(request, false); 158 if (serverUrl != null) { 159 String webAppName = getWebAppName(request); 160 161 baseURL = StringUtils.isNotBlank(webAppName) ? serverUrl + webAppName + '/' : serverUrl; 162 163 } 164 return baseURL; 165 } 166 167 /** 168 * Returns the context path of the application. Try to get it from the {@code ServletRequest} and then from the 169 * {@code org.nuxeo.ecm.contextPath} system property. Fallback on default context path {@code /nuxeo}. 170 */ 171 public static String getContextPath(ServletRequest request) { 172 HttpServletRequest httpRequest = getHttpServletRequest(request); 173 String contextPath = null; 174 if (httpRequest != null) { 175 contextPath = httpRequest.getContextPath(); 176 } 177 return contextPath != null ? contextPath : getContextPathProperty(); 178 } 179 180 public static String getContextPathProperty() { 181 return Framework.getProperty("org.nuxeo.ecm.contextPath", "/nuxeo"); 182 } 183 184 /** 185 * Computes the url to be redirected when logging out 186 * 187 * @return redirect URL as protocol://serverName:port/webappName/... 188 * @since 9.1 189 */ 190 public static String getRedirectUrl(HttpServletRequest request) { 191 String redirectURL = getBaseURL(request); 192 if (request.getAttribute(REQUESTED_URL) != null) { 193 redirectURL += request.getAttribute(REQUESTED_URL); 194 } else if (request.getParameter(REQUESTED_URL) != null) { 195 redirectURL += request.getParameter(REQUESTED_URL); 196 } else { 197 redirectURL = request.getRequestURL().toString(); 198 String queryString = request.getQueryString(); 199 if (queryString != null) { 200 redirectURL += '?' + queryString; 201 } 202 } 203 return redirectURL; 204 } 205 206}