/*
 * This is part of Geomajas, a GIS framework, http://www.geomajas.org/.
 *
 * Copyright 2008-2011 Geosparc nv, http://www.geosparc.com/, Belgium.
 *
 * The program is available in open source according to the GNU Affero
 * General Public License. All contributions in this program are covered
 * by the Geomajas Contributors License Agreement. For full licensing
 * details, see LICENSE.txt in the project root.
 */

package org.geomajas.servlet;

import org.geomajas.service.DispatcherUrlService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * {@link org.geomajas.service.DispatcherUrlService} which tries to automatically detect the dispatcher server address.
 *
 * @author Joachim Van der Auwera
 * @author Oliver May
 */
@Component
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class AutomaticDispatcherUrlService implements DispatcherUrlService {

	private static final String X_FOWARD_HOST_HEADER = "X-Forwarded-Host";
	private static final String X_GWT_MODULE_HEADER = "X-GWT-Module-Base";
	
	private Logger log = LoggerFactory.getLogger(AutomaticDispatcherUrlService.class);

	public String getDispatcherUrl() {
		RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
		if (null == requestAttributes || !(requestAttributes instanceof ServletRequestAttributes)) {
			log.warn("Trying to automatically get the dispatcher URL, but not running inside a servlet request. " +
					"You are recommended to use StaticDispatcherUrlService");
			return "./d/"; // use relative URL as back-up, will fail in many cases
		}

		HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();

		// X-Forwarded-Host if behind a reverse proxy, fallback to general method.
		// Alternative we could use the gwt module url to guess the real URL.
		if (null != request.getHeader(X_FOWARD_HOST_HEADER)) {
			log.warn("Automaticdispatcherservice detected a X-Forwarded-Host header which means the server is " +
					"accessed using a reverse proxy server. This might cause problems in some cases. You are " +
					"recommended to configure your tomcat connector to be aware of the original url. " +
					"(see http://tomcat.apache.org/tomcat-6.0-doc/proxy-howto.html )");
			String gwtModuleBase = request.getHeader(X_GWT_MODULE_HEADER);
			if (null != gwtModuleBase) {
				// Get last slash in the gwtModuleBase, ignoring the trailing slash.
				int contextEndIndex = gwtModuleBase.lastIndexOf("/", gwtModuleBase.length() - 2);
				if (contextEndIndex > -1) {
					String url = gwtModuleBase.substring(0, contextEndIndex) + "/d/";
					return url;
				}
			} // else use the standard method below
		}
		
		String url = request.getScheme() + "://" + request.getServerName();
		if (80 != request.getServerPort()) {
			url += ":" + request.getServerPort();
		}
		String cp = request.getContextPath();
		if (null != cp && cp.length() > 0) {
			url += request.getContextPath();
		}
		url += "/d/";
		return url;
	}
}

@@ -444,16 +444,47 @@
 rvlet;%0A%0A
+import java.util.Enumeration;%0A%0A
 import o
@@ -2136,16 +2136,66 @@
 est();%0A%0A
+%09%09String serverName = request.getServerName();%0A%09%09%0A
 %09%09// X-F
@@ -2824,16 +2824,75 @@
 EADER);%0A
+%09%09%09Enumeration%3CString%3E headers = request.getHeaderNames();%0A
 %09%09%09if (n
@@ -3209,45 +3209,181 @@
 %09%09%7D 
-// else use the standard method below
+else %7B%0A%09%09%09%09// else get the information from the X-forwarded-host header and default to the standard behaviour %0A%09%09%09%09serverName = request.getHeader(X_FOWARD_HOST_HEADER);%0A%09%09%09%7D
 %0A%09%09%7D
@@ -3427,36 +3427,25 @@
 ) + %22://%22 + 
-request.getS
+s
 erverName();
@@ -3437,26 +3437,24 @@
 + serverName
-()
 ;%0A%09%09if (80 !

Use x-forwarded-for in the default fallback