Added support for configuring the connection. SMACK-113 SMACK-114

git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@3311 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
Gaston Dombiak 2006-01-17 20:05:31 +00:00 committed by gato
parent c00abdeffd
commit 39eca6ec5b
3 changed files with 99 additions and 89 deletions

View File

@ -138,6 +138,10 @@ public class XMPPConnection {
* Flag that indicates if stream compression is actually in use. * Flag that indicates if stream compression is actually in use.
*/ */
private boolean usingCompression; private boolean usingCompression;
/**
* Holds the initial configuration used while creating the connection.
*/
private ConnectionConfiguration configuration;
/** /**
* Creates a new connection to the specified XMPP server. A DNS SRV lookup will be * Creates a new connection to the specified XMPP server. A DNS SRV lookup will be
@ -154,27 +158,17 @@ public class XMPPConnection {
* appropiate error messages to end-users. * appropiate error messages to end-users.
*/ */
public XMPPConnection(String serviceName) throws XMPPException { public XMPPConnection(String serviceName) throws XMPPException {
// Perform DNS lookup to get host and port to use
DNSUtil.HostAddress address = DNSUtil.resolveXMPPDomain(serviceName); DNSUtil.HostAddress address = DNSUtil.resolveXMPPDomain(serviceName);
// Create the configuration for this new connection
this.host = address.getHost(); ConnectionConfiguration config =
this.port = address.getPort(); new ConnectionConfiguration(address.getHost(), address.getPort(), serviceName);
try { config.setTLSEnabled(true);
this.socket = new Socket(host, port); config.setCompressionEnabled(false);
} config.setSASLAuthenticationEnabled(true);
catch (UnknownHostException uhe) { config.setDebuggerEnabled(DEBUG_ENABLED);
throw new XMPPException( // Set the new connection configuration
"Could not connect to " + host + ":" + port + ".", connectUsingConfiguration(config, null);
new XMPPError(504),
uhe);
}
catch (IOException ioe) {
throw new XMPPException(
"XMPPError connecting to " + host + ":" + port + ".",
new XMPPError(502),
ioe);
}
this.serviceName = serviceName;
init();
} }
/** /**
@ -189,25 +183,14 @@ public class XMPPConnection {
* appropiate error messages to end-users. * appropiate error messages to end-users.
*/ */
public XMPPConnection(String host, int port) throws XMPPException { public XMPPConnection(String host, int port) throws XMPPException {
this.host = host; // Create the configuration for this new connection
this.port = port; ConnectionConfiguration config = new ConnectionConfiguration(host, port);
try { config.setTLSEnabled(true);
this.socket = new Socket(host, port); config.setCompressionEnabled(false);
} config.setSASLAuthenticationEnabled(true);
catch (UnknownHostException uhe) { config.setDebuggerEnabled(DEBUG_ENABLED);
throw new XMPPException( // Set the new connection configuration
"Could not connect to " + host + ":" + port + ".", connectUsingConfiguration(config, null);
new XMPPError(504),
uhe);
}
catch (IOException ioe) {
throw new XMPPException(
"XMPPError connecting to " + host + ":" + port + ".",
new XMPPError(502),
ioe);
}
this.serviceName = host;
init();
} }
/** /**
@ -223,25 +206,14 @@ public class XMPPConnection {
* appropiate error messages to end-users. * appropiate error messages to end-users.
*/ */
public XMPPConnection(String host, int port, String serviceName) throws XMPPException { public XMPPConnection(String host, int port, String serviceName) throws XMPPException {
this.host = host; // Create the configuration for this new connection
this.port = port; ConnectionConfiguration config = new ConnectionConfiguration(host, port, serviceName);
try { config.setTLSEnabled(true);
this.socket = new Socket(host, port); config.setCompressionEnabled(false);
} config.setSASLAuthenticationEnabled(true);
catch (UnknownHostException uhe) { config.setDebuggerEnabled(DEBUG_ENABLED);
throw new XMPPException( // Set the new connection configuration
"Could not connect to " + host + ":" + port + ".", connectUsingConfiguration(config, null);
new XMPPError(504),
uhe);
}
catch (IOException ioe) {
throw new XMPPException(
"XMPPError connecting to " + host + ":" + port + ".",
new XMPPError(502),
ioe);
}
this.serviceName = serviceName;
init();
} }
/** /**
@ -266,10 +238,38 @@ public class XMPPConnection {
public XMPPConnection(String host, int port, String serviceName, SocketFactory socketFactory) public XMPPConnection(String host, int port, String serviceName, SocketFactory socketFactory)
throws XMPPException throws XMPPException
{ {
this.host = host; // Create the configuration for this new connection
this.port = port; ConnectionConfiguration config = new ConnectionConfiguration(host, port, serviceName);
config.setTLSEnabled(true);
config.setCompressionEnabled(false);
config.setSASLAuthenticationEnabled(true);
config.setDebuggerEnabled(DEBUG_ENABLED);
// Set the new connection configuration
connectUsingConfiguration(config, socketFactory);
}
public XMPPConnection(ConnectionConfiguration config) throws XMPPException {
// Set the new connection configuration
connectUsingConfiguration(config, null);
}
public XMPPConnection(ConnectionConfiguration config, SocketFactory socketFactory)
throws XMPPException {
// Set the new connection configuration
connectUsingConfiguration(config, socketFactory);
}
private void connectUsingConfiguration(ConnectionConfiguration config,
SocketFactory socketFactory) throws XMPPException {
this.host = config.getHost();
this.port = config.getPort();
try { try {
this.socket = socketFactory.createSocket(host, port); if (socketFactory == null) {
this.socket = new Socket(host, port);
}
else {
this.socket = socketFactory.createSocket(host, port);
}
} }
catch (UnknownHostException uhe) { catch (UnknownHostException uhe) {
throw new XMPPException( throw new XMPPException(
@ -283,8 +283,13 @@ public class XMPPConnection {
new XMPPError(502), new XMPPError(502),
ioe); ioe);
} }
this.serviceName = serviceName; this.serviceName = config.getServiceName();
this.configuration = config;
init(); init();
// If compression is enabled then request the server to use stream compression
if (config.isCompressionEnabled()) {
useCompression();
}
} }
/** /**
@ -414,7 +419,8 @@ public class XMPPConnection {
username = username.toLowerCase().trim(); username = username.toLowerCase().trim();
String response = null; String response = null;
if (saslAuthentication.hasNonAnonymousAuthentication()) { if (configuration.isSASLAuthenticationEnabled() &&
saslAuthentication.hasNonAnonymousAuthentication()) {
// Authenticate using SASL // Authenticate using SASL
response = saslAuthentication.authenticate(username, password, resource); response = saslAuthentication.authenticate(username, password, resource);
} }
@ -453,7 +459,7 @@ public class XMPPConnection {
// name we are now logged-in as. // name we are now logged-in as.
// If DEBUG_ENABLED was set to true AFTER the connection was created the debugger // If DEBUG_ENABLED was set to true AFTER the connection was created the debugger
// will be null // will be null
if (DEBUG_ENABLED && debugger != null) { if (configuration.isDebuggerEnabled() && debugger != null) {
debugger.userHasLogged(user); debugger.userHasLogged(user);
} }
} }
@ -477,7 +483,8 @@ public class XMPPConnection {
} }
String response = null; String response = null;
if (saslAuthentication.hasAnonymousAuthentication()) { if (configuration.isSASLAuthenticationEnabled() &&
saslAuthentication.hasAnonymousAuthentication()) {
response = saslAuthentication.authenticateAnonymously(); response = saslAuthentication.authenticateAnonymously();
} }
else { else {
@ -504,7 +511,7 @@ public class XMPPConnection {
// name we are now logged-in as. // name we are now logged-in as.
// If DEBUG_ENABLED was set to true AFTER the connection was created the debugger // If DEBUG_ENABLED was set to true AFTER the connection was created the debugger
// will be null // will be null
if (DEBUG_ENABLED && debugger != null) { if (configuration.isDebuggerEnabled() && debugger != null) {
debugger.userHasLogged(user); debugger.userHasLogged(user);
} }
} }
@ -840,7 +847,7 @@ public class XMPPConnection {
// If debugging is enabled, we should start the thread that will listen for // If debugging is enabled, we should start the thread that will listen for
// all packets and then log them. // all packets and then log them.
if (DEBUG_ENABLED) { if (configuration.isDebuggerEnabled()) {
packetReader.addPacketListener(debugger.getReaderListener(), null); packetReader.addPacketListener(debugger.getReaderListener(), null);
if (debugger.getWriterListener() != null) { if (debugger.getWriterListener() != null) {
packetWriter.addPacketListener(debugger.getWriterListener(), null); packetWriter.addPacketListener(debugger.getWriterListener(), null);
@ -959,7 +966,7 @@ public class XMPPConnection {
} }
// If debugging is enabled, we open a window and write out all network traffic. // If debugging is enabled, we open a window and write out all network traffic.
if (DEBUG_ENABLED) { if (configuration.isDebuggerEnabled()) {
if (debugger == null) { if (debugger == null) {
// Detect the debugger class to use. // Detect the debugger class to use.
String className = null; String className = null;
@ -1061,6 +1068,10 @@ public class XMPPConnection {
* want to secure the connection. * want to secure the connection.
*/ */
void startTLSReceived() { void startTLSReceived() {
if (!configuration.isTLSEnabled()) {
// Do not secure the connection using TLS since TLS was disabled
return;
}
try { try {
writer.write("<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>"); writer.write("<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>");
writer.flush(); writer.flush();
@ -1077,9 +1088,9 @@ public class XMPPConnection {
*/ */
void proceedTLSReceived() throws Exception { void proceedTLSReceived() throws Exception {
SSLContext context = SSLContext.getInstance("TLS"); SSLContext context = SSLContext.getInstance("TLS");
// Accept any certificate presented by the server // Verify certificate presented by the server
context.init(null, // KeyManager not required context.init(null, // KeyManager not required
new javax.net.ssl.TrustManager[]{new OpenTrustManager()}, new javax.net.ssl.TrustManager[]{new ServerTrustManager(serviceName, configuration)},
new java.security.SecureRandom()); new java.security.SecureRandom());
Socket plain = socket; Socket plain = socket;
// Secure the plain connection // Secure the plain connection
@ -1120,15 +1131,6 @@ public class XMPPConnection {
return compressionMethods != null && compressionMethods.contains(method); return compressionMethods != null && compressionMethods.contains(method);
} }
/**
* Returns true if the server offered stream compression to the client.
*
* @return true if the server offered stream compression to the client.
*/
public boolean getServerSupportsCompression() {
return compressionMethods != null && !compressionMethods.isEmpty();
}
/** /**
* Returns true if network traffic is being compressed. When using stream compression network * Returns true if network traffic is being compressed. When using stream compression network
* traffic can be reduced up to 90%. Therefore, stream compression is ideal when using a slow * traffic can be reduced up to 90%. Therefore, stream compression is ideal when using a slow
@ -1157,7 +1159,7 @@ public class XMPPConnection {
* *
* @return true if stream compression negotiation was successful. * @return true if stream compression negotiation was successful.
*/ */
public boolean useCompression() { private boolean useCompression() {
// If stream compression was offered by the server and we want to use // If stream compression was offered by the server and we want to use
// compression then send compression request to the server // compression then send compression request to the server
if (authenticated) { if (authenticated) {

View File

@ -27,6 +27,7 @@ import javax.net.SocketFactory;
import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.xmlpull.v1.*; import org.xmlpull.v1.*;
import org.xmlpull.mxp1.MXParser; import org.xmlpull.mxp1.MXParser;
@ -184,11 +185,16 @@ public abstract class SmackTestCase extends TestCase {
try { try {
// Connect to the server // Connect to the server
for (int i = 0; i < getMaxConnections(); i++) { for (int i = 0; i < getMaxConnections(); i++) {
// Create the configuration for this new connection
ConnectionConfiguration config = new ConnectionConfiguration(host, port);
config.setTLSEnabled(true);
config.setCompressionEnabled(Boolean.getBoolean("test.compressionEnabled"));
config.setSASLAuthenticationEnabled(true);
if (getSocketFactory() == null) { if (getSocketFactory() == null) {
connections[i] = new XMPPConnection(host, port); connections[i] = new XMPPConnection(config);
} }
else { else {
connections[i] = new XMPPConnection(host, port, host, getSocketFactory()); connections[i] = new XMPPConnection(config, getSocketFactory());
} }
} }
// Use the host name that the server reports. This is a good idea in most // Use the host name that the server reports. This is a good idea in most
@ -206,13 +212,10 @@ public abstract class SmackTestCase extends TestCase {
getConnection(i).getAccountManager().createAccount("user" + i, "user" + i); getConnection(i).getAccountManager().createAccount("user" + i, "user" + i);
} catch (XMPPException e) { } catch (XMPPException e) {
// Do nothing if the accout already exists // Do nothing if the accout already exists
if (e.getXMPPError().getCode() != 409) { if (e.getXMPPError() == null || e.getXMPPError().getCode() != 409) {
throw e; throw e;
} }
} }
if (Boolean.getBoolean("test.compressionEnabled")) {
getConnection(i).useCompression();
}
// Login with the new test account // Login with the new test account
getConnection(i).login("user" + i, "user" + i); getConnection(i).login("user" + i, "user" + i);
} }

View File

@ -23,6 +23,8 @@ package org.jivesoftware.smackx;
import org.jivesoftware.smack.test.SmackTestCase; import org.jivesoftware.smack.test.SmackTestCase;
import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.SmackConfiguration;
/** /**
* Ensure that stream compression (JEP-138) is correctly supported by Smack. * Ensure that stream compression (JEP-138) is correctly supported by Smack.
@ -40,11 +42,14 @@ public class CompressionTest extends SmackTestCase {
* stream compression enabled. * stream compression enabled.
*/ */
public void testSuccessCompression() throws XMPPException { public void testSuccessCompression() throws XMPPException {
XMPPConnection connection = new XMPPConnection(getHost(), getPort());
assertTrue("Server doesn't support stream compression", connection.getServerSupportsCompression()); // Create the configuration for this new connection
ConnectionConfiguration config = new ConnectionConfiguration(getHost(), getPort());
config.setTLSEnabled(true);
config.setCompressionEnabled(true);
config.setSASLAuthenticationEnabled(true);
assertTrue("Failed to negotiate stream compression", connection.useCompression()); XMPPConnection connection = new XMPPConnection(config);
assertTrue("Connection is not using stream compression", connection.isUsingCompression()); assertTrue("Connection is not using stream compression", connection.isUsingCompression());