Commit 37418e69 authored by guus's avatar guus

Allow the generated crossdomain.xml for BOSH to be overridden (OF-340).

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@11581 b35dd754-fafc-0310-a699-88a17e54d16e
parent 7adf708d
...@@ -19,31 +19,45 @@ ...@@ -19,31 +19,45 @@
*/ */
package org.jivesoftware.openfire.http; package org.jivesoftware.openfire.http;
import org.jivesoftware.openfire.XMPPServer; import java.io.BufferedReader;
import org.jivesoftware.util.JiveGlobals; import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.util.JiveGlobals;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* Serves up the flash cross domain xml file which allows other domains to access http-binding * Serves up the flash cross domain xml file which allows other domains to
* using flash. * access http-binding using flash.
*
* This implementation will first try to serve
* <tt>&lt;OpenfireHome&gt;/conf/crossdomain.xml</tt>. If this file is
* unavailable, a crossdomain file will be generated dynamically, based on the
* current settings of the Openfire BOSH functionality.
* *
* @author Alexander Wenckus * @author Alexander Wenckus
* @author Guus der Kinderen, guus.der.kinderen@gmail.com
*/ */
public class FlashCrossDomainServlet extends HttpServlet { public class FlashCrossDomainServlet extends HttpServlet {
public static String CROSS_DOMAIN_TEXT = "<?xml version=\"1.0\"?>" + private static Logger Log = LoggerFactory.getLogger(FlashCrossDomainServlet.class);
"<!DOCTYPE cross-domain-policy SYSTEM \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\">" +
"<cross-domain-policy>" + public static String CROSS_DOMAIN_TEXT = "<?xml version=\"1.0\"?>\n" +
"<site-control permitted-cross-domain-policies=\"all\"/>" + "<!DOCTYPE cross-domain-policy SYSTEM \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\">\n" +
"<allow-access-from domain=\"*\" to-ports=\""; "<cross-domain-policy>\n" +
"\t<site-control permitted-cross-domain-policies=\"all\"/>\n" +
"\t<allow-access-from domain=\"*\" to-ports=\"";
public static String CROSS_DOMAIN_MIDDLE_TEXT = "\" secure=\""; public static String CROSS_DOMAIN_MIDDLE_TEXT = "\" secure=\"";
public static String CROSS_DOMAIN_END_TEXT = "\"/></cross-domain-policy>"; public static String CROSS_DOMAIN_END_TEXT = "\"/>\n</cross-domain-policy>";
private static String CROSS_DOMAIN_SECURE_ENABLED = "httpbind.crossdomain.secure"; private static String CROSS_DOMAIN_SECURE_ENABLED = "httpbind.crossdomain.secure";
private static boolean CROSS_DOMAIN_SECURE_DEFAULT = true; private static boolean CROSS_DOMAIN_SECURE_DEFAULT = true;
...@@ -52,18 +66,89 @@ public class FlashCrossDomainServlet extends HttpServlet { ...@@ -52,18 +66,89 @@ public class FlashCrossDomainServlet extends HttpServlet {
protected void doGet(HttpServletRequest httpServletRequest, protected void doGet(HttpServletRequest httpServletRequest,
HttpServletResponse response) throws HttpServletResponse response) throws
ServletException, IOException { ServletException, IOException {
StringBuilder builder = new StringBuilder(); response.setContentType("text/xml");
response.getOutputStream().write(getCrossDomainContent().getBytes());
}
/**
* Returns the content for <tt>crossdomain.xml</tt>, either by generating
* content, or by passing the provided file in
* <tt>&lt;OpenfireHome&gt;/conf/crossdomain.xml</tt>
*
* @return content for the <tt>crossdomain.xml</tt> that should be served
* for this service.
*/
public static String getCrossDomainContent() {
final String override = getContent(getOverride());
if (override != null && override.trim().length() > 0) {
return override;
} else {
return generateOutput();
}
}
/**
* Returns <tt>&lt;OpenfireHome&gt;/conf/crossdomain.xml</tt> as a File
* object (even if the file does not exist on the file system).
*
* @return <tt>&lt;OpenfireHome&gt;/conf/crossdomain.xml</tt>
*/
private static File getOverride() {
final StringBuilder sb = new StringBuilder();
sb.append(JiveGlobals.getHomeDirectory());
if (!sb.substring(sb.length()-1).startsWith(File.separator)) {
sb.append(File.separator);
}
sb.append("conf");
sb.append(File.separator);
return new File(sb.toString(), "crossdomain.xml");
}
/**
* Return content of the provided file as a String.
*
* @param file
* The file from which to get the content.
* @return String-based content of the provided file.
*/
private static String getContent(File file) {
final StringBuilder content = new StringBuilder();
if (file.canRead()) {
try {
final BufferedReader in = new BufferedReader(new FileReader(
file));
String str;
while ((str = in.readLine()) != null) {
content.append(str);
content.append('\n');
}
in.close();
} catch (IOException ex) {
Log.warn("Unexpected exception while trying to read file: " + file.getName(), ex);
return null;
}
}
return content.toString();
}
/**
* Dynamically generates content for a non-restrictive <tt>crossdomain.xml</tt> file.
*/
private static String generateOutput() {
final StringBuilder builder = new StringBuilder();
builder.append(CROSS_DOMAIN_TEXT); builder.append(CROSS_DOMAIN_TEXT);
getPortList(builder); getPortList(builder);
builder.append(CROSS_DOMAIN_MIDDLE_TEXT); builder.append(CROSS_DOMAIN_MIDDLE_TEXT);
getSecure(builder); getSecure(builder);
builder.append(CROSS_DOMAIN_END_TEXT); builder.append(CROSS_DOMAIN_END_TEXT);
builder.append("\n"); builder.append("\n");
response.setContentType("text/xml");
response.getOutputStream().write(builder.toString().getBytes()); return builder.toString();
} }
private StringBuilder getPortList(StringBuilder builder) { private static StringBuilder getPortList(StringBuilder builder) {
boolean multiple = false; boolean multiple = false;
if(XMPPServer.getInstance().getConnectionManager().getClientListenerPort() > 0) { if(XMPPServer.getInstance().getConnectionManager().getClientListenerPort() > 0) {
builder.append(XMPPServer.getInstance().getConnectionManager().getClientListenerPort()); builder.append(XMPPServer.getInstance().getConnectionManager().getClientListenerPort());
...@@ -97,7 +182,7 @@ public class FlashCrossDomainServlet extends HttpServlet { ...@@ -97,7 +182,7 @@ public class FlashCrossDomainServlet extends HttpServlet {
return builder; return builder;
} }
private StringBuilder getSecure(StringBuilder builder) { private static StringBuilder getSecure(StringBuilder builder) {
if (JiveGlobals.getBooleanProperty(CROSS_DOMAIN_SECURE_ENABLED,CROSS_DOMAIN_SECURE_DEFAULT)) { if (JiveGlobals.getBooleanProperty(CROSS_DOMAIN_SECURE_ENABLED,CROSS_DOMAIN_SECURE_DEFAULT)) {
builder.append("true"); builder.append("true");
} else { } else {
......
...@@ -9,9 +9,12 @@ ...@@ -9,9 +9,12 @@
- agreement with Jive. - agreement with Jive.
--%> --%>
<%@ page import="org.jivesoftware.util.ParamUtils" %> <%@ page import="org.jivesoftware.util.ParamUtils" %>
<%@ page import="java.io.File" %>
<%@ page import="java.util.Map" %> <%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %> <%@ page import="java.util.HashMap" %>
<%@ page import="org.jivesoftware.util.Log" %> <%@ page import="org.jivesoftware.util.Log" %>
<%@ page import="org.jivesoftware.util.StringUtils" %>
<%@ page import="org.jivesoftware.openfire.http.FlashCrossDomainServlet" %>
<%@ page import="org.jivesoftware.openfire.http.HttpBindManager" %> <%@ page import="org.jivesoftware.openfire.http.HttpBindManager" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %> <%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
...@@ -61,7 +64,8 @@ ...@@ -61,7 +64,8 @@
int securePort = serverManager.getHttpBindSecurePort(); int securePort = serverManager.getHttpBindSecurePort();
boolean isScriptSyntaxEnabled = serverManager.isScriptSyntaxEnabled(); boolean isScriptSyntaxEnabled = serverManager.isScriptSyntaxEnabled();
%> %>
<html>
<%@page import="org.jivesoftware.openfire.http.FlashCrossDomainServlet"%><html>
<head> <head>
<title> <title>
<fmt:message key="httpbind.settings.title"/> <fmt:message key="httpbind.settings.title"/>
...@@ -70,10 +74,11 @@ ...@@ -70,10 +74,11 @@
<script type="text/javascript"> <script type="text/javascript">
var enabled = <%=isHttpBindEnabled%>; var enabled = <%=isHttpBindEnabled%>;
var setEnabled = function() { var setEnabled = function() {
$("port").disabled = !enabled $("port").disabled = !enabled;
$("securePort").disabled = !enabled; $("securePort").disabled = !enabled;
$("rb03").disabled = !enabled $("rb03").disabled = !enabled;
$("rb04").disabled = !enabled $("rb04").disabled = !enabled;
$("crossdomain").disabled = !enabled;
} }
window.onload = setTimeout("setEnabled()", 500); window.onload = setTimeout("setEnabled()", 500);
</script> </script>
...@@ -185,6 +190,14 @@ ...@@ -185,6 +190,14 @@
</tbody> </tbody>
</table> </table>
</div> </div>
<div class="jive-contentBoxHeader">Cross-domain policy</div>
<div class="jive-contentbox">
<p>By default, Openfire will generate a <tt>crossdomain.xml</tt> file, hosted at the root of the webservice that offers BOSH functionality. This generated file will allow all access on all relevant ports.</p>
<p>This default behavior can be overridden with a custom file. If such a file is made accessible at <tt>&lt;openfireHome&gt;<%=File.separator%>conf<%=File.separator%>crossdomain.xml</tt>, its content will be used, instead of the generated content.</p>
<p>This is current <tt>crossdomain.xml</tt> content, as it is presented to your users:</p>
<textarea id="crossdomain" cols="120" rows="10" wrap="virtual" readonly="readonly"><%= (isHttpBindEnabled ? StringUtils.escapeForXML(FlashCrossDomainServlet.getCrossDomainContent()) : "") %></textarea>
</div>
<input type="submit" id="settingsUpdate" name="update" <input type="submit" id="settingsUpdate" name="update"
value="<fmt:message key="global.save_settings" />"> value="<fmt:message key="global.save_settings" />">
</form> </form>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment