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 @@
+
- "/>