1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/**
* $RCSfile$
* $Revision: $
* $Date: $
*
* Copyright (C) 2005-2008 Jive Software. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.openfire.http;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
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 using flash.
*
* This implementation will first try to serve
* <tt><OpenfireHome>/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 Guus der Kinderen, guus.der.kinderen@gmail.com
*/
public class FlashCrossDomainServlet extends HttpServlet {
private static Logger Log = LoggerFactory.getLogger(FlashCrossDomainServlet.class);
public static String CROSS_DOMAIN_TEXT = "<?xml version=\"1.0\"?>\n" +
"<!DOCTYPE cross-domain-policy SYSTEM \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\">\n" +
"<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_END_TEXT = "\"/>\n</cross-domain-policy>";
private static String CROSS_DOMAIN_SECURE_ENABLED = "httpbind.crossdomain.secure";
private static boolean CROSS_DOMAIN_SECURE_DEFAULT = true;
@Override
protected void doGet(HttpServletRequest httpServletRequest,
HttpServletResponse response) throws
ServletException, IOException {
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><OpenfireHome>/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><OpenfireHome>/conf/crossdomain.xml</tt> as a File
* object (even if the file does not exist on the file system).
*
* @return <tt><OpenfireHome>/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);
getPortList(builder);
builder.append(CROSS_DOMAIN_MIDDLE_TEXT);
getSecure(builder);
builder.append(CROSS_DOMAIN_END_TEXT);
builder.append("\n");
return builder.toString();
}
private static StringBuilder getPortList(StringBuilder builder) {
boolean multiple = false;
if(XMPPServer.getInstance().getConnectionManager().getClientListenerPort() > 0) {
builder.append(XMPPServer.getInstance().getConnectionManager().getClientListenerPort());
multiple = true;
}
if(XMPPServer.getInstance().getConnectionManager().getClientSSLListenerPort() > 0) {
if(multiple) {
builder.append(",");
}
builder.append(XMPPServer.getInstance().getConnectionManager().getClientSSLListenerPort());
multiple = true;
}
if(HttpBindManager.getInstance().isHttpBindEnabled()) {
// ports for http-binding may not be strictly needed in here, but it doesn't hurt
if(HttpBindManager.getInstance().getHttpBindUnsecurePort() > 0) {
if(multiple) {
builder.append(",");
}
builder.append(HttpBindManager.getInstance().getHttpBindUnsecurePort());
multiple = true;
}
if (HttpBindManager.getInstance().isHttpsBindActive()) {
if (multiple) {
builder.append(",");
}
builder.append(HttpBindManager.getInstance().getHttpBindSecurePort());
}
}
return builder;
}
private static StringBuilder getSecure(StringBuilder builder) {
if (JiveGlobals.getBooleanProperty(CROSS_DOMAIN_SECURE_ENABLED,CROSS_DOMAIN_SECURE_DEFAULT)) {
builder.append("true");
} else {
builder.append("false");
}
return builder;
}
}