001/*
002 * (C) Copyright 2006-2008 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Nuxeo - initial API and implementation
016 *
017 * $Id$
018 */
019
020package org.nuxeo.ecm.webengine.jaxrs.coreiodelegate;
021
022import javax.servlet.ServletRequest;
023import javax.servlet.http.HttpServletRequest;
024
025import org.apache.commons.lang.StringUtils;
026import org.apache.commons.logging.Log;
027import org.apache.commons.logging.LogFactory;
028import org.nuxeo.runtime.api.Framework;
029
030/**
031 * @deprecated Duplicate of org.nuxeo.ecm.platform.web.common.vh.VirtualHostHelper
032 * @since 7.2
033 */
034@Deprecated
035public class VirtualHostHelper {
036
037    private static final int HTTP_PORT_NUMBER = 80;
038
039    private static final int HTTPS_PORT_NUMBER = 443;
040
041    private static final Log log = LogFactory.getLog(VirtualHostHelper.class);
042
043    private static final String X_FORWARDED_HOST = "x-forwarded-host";
044
045    private static final String X_FORWARDED_PROTO = "x-forwarded-proto";
046
047    private static final String X_FORWARDED_PORT = "x-forwarded-port";
048
049    private static final String VH_HEADER = "nuxeo-virtual-host";
050
051    private static final String VH_PARAM = "nuxeo.virtual.host";
052
053    // Utility class.
054    private VirtualHostHelper() {
055    }
056
057    private static HttpServletRequest getHttpServletRequest(ServletRequest request) {
058        if (request instanceof HttpServletRequest) {
059            return (HttpServletRequest) request;
060        }
061        return null;
062    }
063
064    /**
065     * @return WebApp name : ie : nuxeo
066     */
067    public static String getWebAppName(ServletRequest request) {
068        return getContextPath(request).replace("/", "");
069    }
070
071    /**
072     * @return Server URL as : protocol://serverName:port/
073     */
074    public static String getServerURL(ServletRequest request) {
075        return getServerURL(request, false);
076    }
077
078    private static String getServerUrl(String scheme, String serverName, int serverPort) {
079        StringBuilder sbaseURL = new StringBuilder();
080        sbaseURL.append(scheme);
081        sbaseURL.append("://");
082        sbaseURL.append(serverName);
083        if (serverPort != 0) {
084            if ("http".equals(scheme) && serverPort != HTTP_PORT_NUMBER || "https".equals(scheme)
085                    && serverPort != HTTPS_PORT_NUMBER) {
086                sbaseURL.append(':');
087                sbaseURL.append(serverPort);
088            }
089        }
090        sbaseURL.append('/');
091        return sbaseURL.toString();
092    }
093
094    /**
095     * @return Server URL as : protocol://serverName:port/
096     */
097    public static String getServerURL(ServletRequest request, boolean local) {
098        String baseURL = null;
099        HttpServletRequest httpRequest = getHttpServletRequest(request);
100        if (httpRequest != null) {
101            // Detect Nuxeo specific header for VH
102            String nuxeoVH = httpRequest.getHeader(VH_HEADER);
103            if (nuxeoVH == null) {
104                nuxeoVH = Framework.getProperty(VH_PARAM);
105            }
106            if (!local && nuxeoVH != null && nuxeoVH.contains("http")) {
107                baseURL = nuxeoVH;
108            } else {
109                // default values
110                String serverName = httpRequest.getServerName();
111                int serverPort = httpRequest.getServerPort();
112                String scheme = httpRequest.getScheme();
113
114                if (!local) {
115                    String forwardedPort = httpRequest.getHeader(X_FORWARDED_PORT);
116
117                    if (forwardedPort != null) {
118                        try {
119                            serverPort = Integer.parseInt(forwardedPort);
120                        } catch (NumberFormatException e) {
121                            log.error("Unable to get forwarded port from header", e);
122                        }
123                    }
124
125                    String forwardedProto = httpRequest.getHeader(X_FORWARDED_PROTO);
126                    if (forwardedProto != null) {
127                        scheme = forwardedProto;
128                    }
129
130                    // Detect virtual hosting based in standard header
131                    String forwardedHost = httpRequest.getHeader(X_FORWARDED_HOST);
132                    if (forwardedHost != null) {
133                        if (forwardedHost.contains(":")) {
134                            serverName = forwardedHost.split(":")[0];
135                            serverPort = Integer.valueOf(forwardedHost.split(":")[1]);
136                        } else {
137                            serverName = forwardedHost;
138                            serverPort = HTTP_PORT_NUMBER; // fallback
139                        }
140                    }
141                }
142
143                baseURL = getServerUrl(scheme, serverName, serverPort);
144            }
145        }
146        if (baseURL == null) {
147            log.error("Could not retrieve base url correctly");
148            log.debug("Could not retrieve base url correctly", new Throwable());
149        }
150        return baseURL;
151    }
152
153    /**
154     * @return base URL as protocol://serverName:port/webappName/
155     */
156    public static String getBaseURL(ServletRequest request) {
157        String baseURL = null;
158        String serverUrl = getServerURL(request, false);
159        if (serverUrl != null) {
160            String webAppName = getWebAppName(request);
161
162            baseURL = StringUtils.isNotBlank(webAppName) ? serverUrl + webAppName + '/' : serverUrl;
163
164        }
165        return baseURL;
166    }
167
168    /**
169     * Returns the context path of the application. Try to get it from the {@code ServletRequest} and then from the
170     * {@code org.nuxeo.ecm.contextPath} system property. Fallback on default context path {@code /nuxeo}.
171     */
172    public static String getContextPath(ServletRequest request) {
173        HttpServletRequest httpRequest = getHttpServletRequest(request);
174        String contextPath = null;
175        if (httpRequest != null) {
176            contextPath = httpRequest.getContextPath();
177        }
178        return contextPath != null ? contextPath : getContextPathProperty();
179    }
180
181    public static String getContextPathProperty() {
182        return Framework.getProperty("org.nuxeo.ecm.contextPath", "/nuxeo");
183    }
184
185}