Allow manual specification of a base URL. From: Michael Smith includes/header.jsp uses org.opennms.web.Util.calculateUrlBase() to come up with an HTML base tag. By default this queries the request to come up with a URL, but now you can override it if it gets it wrong. You can also put in substitutions (scheme, host, port, context path) from the real URL. I needed this to get Jetty working behind an Apache/SSL reverse proxy. (OK, you don't need the variable substitutions just for that. You only need them if you use SSH port forwards to get to your Apache/SSL vhost. Then you can't hardcode the base URL.) opennms-webapp/src/main/webapp/tiles/mainLayout.jsp had its own code to set the base tag. I have changed it to use calculateUrlBase() but I can't test it. --- .../src/main/filtered/etc/opennms.properties | 17 +++++ .../src/main/java/org/opennms/web/Util.java | 86 +++++++++++++++-------- .../web-filtered/WEB-INF/configuration.properties | 9 ++ .../src/main/webapp/tiles/mainLayout.jsp | 3 - 4 files changed, 84 insertions(+), 31 deletions(-) diff --git a/opennms-daemon/src/main/filtered/etc/opennms.properties b/opennms-daemon/src/main/filtered/etc/opennms.properties index e5dea69..cc9b876 100644 --- a/opennms-daemon/src/main/filtered/etc/opennms.properties +++ b/opennms-daemon/src/main/filtered/etc/opennms.properties @@ -110,3 +110,20 @@ org.opennms.netmgt.jetty.port = 8980 # bind address here. If you set this to a value other than 127.0.0.1, # you will need to update the rtc-client and map-client URLs above. #org.opennms.netmgt.jetty.host = 127.0.0.1 + +# If OpenNMS is setting an incorrect HTML tag, you can override +# its idea of the local URL here. The URL must end with a '/'. The following +# substitutions are available: +# %s: scheme (http, https) +# %h, %p: host and port from the Host: header +# %x: host and port from the X-Forwarded-Host, X-Host or Host header +# %c: context path (without trailing slash) +# +# You can use this to get Jetty working behind an Apache/SSL proxy. +# Set the base-url to https://%x%c/ and include in your Apache SSL vhost: +# +# ProxyPass http://127.0.0.1:8980/opennms +# ProxyPassReverse http://127.0.0.1:8980/opennms +# +# +#opennms.web.base-url = https://%x%c/ diff --git a/opennms-webapp/src/main/java/org/opennms/web/Util.java b/opennms-webapp/src/main/java/org/opennms/web/Util.java index 406b037..2686aab 100644 --- a/opennms-webapp/src/main/java/org/opennms/web/Util.java +++ b/opennms-webapp/src/main/java/org/opennms/web/Util.java @@ -66,11 +66,6 @@ import org.opennms.web.element.NetworkElementFactory; public abstract class Util extends Object { /** - * Internal flag used to cache a servlet context parameter - */ - protected static Boolean usePortInBaseUrls; - - /** * Return a string that represents the fully qualified URL for our servlet * context, suitable for use in the HTML base tag. * @@ -79,6 +74,12 @@ public abstract class Util extends Object { * from port 80, and your web application name was "opennms," then this * method would return: http://www.mycompany.com:80/opennms/ *

+ * + *

+ * If this guess is wrong, you can override it by setting the property + * opennms.web.base-url in opennms.properties + * (for embedded Jetty) or WEB-INF/configuration.properties (for Tomcat). + *

* * @param request * the servlet request you are servicing @@ -88,33 +89,60 @@ public abstract class Util extends Object { throw new IllegalArgumentException("Cannot take null parameters."); } - // get what the web browser thinks is the URL - StringBuffer buffer = request.getRequestURL(); - - // get a string version of the buffer so we can search in it - String string = buffer.toString(); - - // find the "//" in something like "http://host" - int schemeSlashesIndex = string.indexOf("//"); - - // find the "/" at the end of "http://host:port/" - int schemeHostPortIndex = string.indexOf("/", schemeSlashesIndex + 2); - - // truncate everything after the base scheme, host, and port values - buffer.setLength(schemeHostPortIndex); - - String context = request.getContextPath(); - - // if the context is not the root context - if (!context.equals("")) { - // context will always start with a slash - buffer.append(context); + String tmpl = Vault.getProperty("opennms.web.base-url"); + if (tmpl == null) { + tmpl = "%s://%x%c/"; } + return substituteUrl(request, tmpl); + } - // add a trailing slash - buffer.append("/"); + protected static final char[] substKeywords = { 's', 'h', 'p', 'x', 'c' }; + + protected static String substituteUrl(HttpServletRequest request, + String tmpl) { + String[] replacements = { + request.getScheme(), // %s + request.getServerName(), // %h + Integer.toString(request.getServerPort()), // %p + getHostHeader(request), // %x + request.getContextPath() // %c + }; + + StringBuffer out = new StringBuffer(48); + for (int i = 0; i < tmpl.length();) { + char c = tmpl.charAt(i++); + if (c == '%' && i < tmpl.length()) { + char d = tmpl.charAt(i++); + for (int key = 0; key < substKeywords.length; ++key) { + if (d == substKeywords[key]) { + out.append(replacements[key]); + break; + } + } + } + else { + out.append(c); + } + } + return out.toString(); + } - return buffer.toString(); + protected static final String[] hostHeaders = { + "X-Forwarded-Host", // Apache ProxyPass + "X-Host", // lighttpd + "Host" // unproxied + }; + + /** Obtains the host and port used by the end user. */ + public static String getHostHeader(HttpServletRequest request) { + for (int i = 0; i < hostHeaders.length; ++i) { + String ret = request.getHeader(hostHeaders[i]); + if (ret != null) { + return ret; + } + } + return request.getServerName() + ":" + + Integer.toString(request.getServerPort()); } /** diff --git a/opennms-webapp/src/main/web-filtered/WEB-INF/configuration.properties b/opennms-webapp/src/main/web-filtered/WEB-INF/configuration.properties index 0ec5398..911452f 100644 --- a/opennms-webapp/src/main/web-filtered/WEB-INF/configuration.properties +++ b/opennms-webapp/src/main/web-filtered/WEB-INF/configuration.properties @@ -53,3 +53,12 @@ org.opennms.rrd.storeByGroup=false # The password the Map System uses when authenticating itself in an HTTP POST. #opennms.map-client.http-post.password = map +# If OpenNMS is setting an incorrect HTML tag, you can override +# its idea of the local URL here. The URL must end with a '/'. The following +# substitutions are available: +# %s: scheme (http, https) +# %h, %p: host and port from the Host: header +# %x: host and port from the X-Forwarded-Host, X-Host or Host header +# %c: context path (without trailing slash) +# +#opennms.web.base-url = https://%x%c/ diff --git a/opennms-webapp/src/main/webapp/tiles/mainLayout.jsp b/opennms-webapp/src/main/webapp/tiles/mainLayout.jsp index 51a2374..3a19b90 100644 --- a/opennms-webapp/src/main/webapp/tiles/mainLayout.jsp +++ b/opennms-webapp/src/main/webapp/tiles/mainLayout.jsp @@ -46,11 +46,10 @@ <tiles:getAsString name="title"/> + - "/>