mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-26 14:02:06 +01:00
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:
parent
c00abdeffd
commit
39eca6ec5b
3 changed files with 99 additions and 89 deletions
|
@ -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,11 +238,39 @@ 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 {
|
||||||
|
if (socketFactory == null) {
|
||||||
|
this.socket = new Socket(host, port);
|
||||||
|
}
|
||||||
|
else {
|
||||||
this.socket = socketFactory.createSocket(host, port);
|
this.socket = socketFactory.createSocket(host, port);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (UnknownHostException uhe) {
|
catch (UnknownHostException uhe) {
|
||||||
throw new XMPPException(
|
throw new XMPPException(
|
||||||
"Could not connect to " + host + ":" + port + ".",
|
"Could not connect to " + host + ":" + port + ".",
|
||||||
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue