mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-23 20:42:06 +01:00
Check for disco support before file transfers
This commit is contained in:
parent
6fad0b9fab
commit
cac35d74b4
6 changed files with 37 additions and 22 deletions
|
@ -22,6 +22,7 @@ import java.util.WeakHashMap;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.jivesoftware.smack.Manager;
|
import org.jivesoftware.smack.Manager;
|
||||||
|
import org.jivesoftware.smack.SmackException;
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
import org.jivesoftware.smack.provider.ExtensionElementProvider;
|
import org.jivesoftware.smack.provider.ExtensionElementProvider;
|
||||||
import org.jivesoftware.smackx.ciphers.Aes256GcmNoPadding;
|
import org.jivesoftware.smackx.ciphers.Aes256GcmNoPadding;
|
||||||
|
@ -82,6 +83,11 @@ public final class JetManager extends Manager implements JingleDescriptionManage
|
||||||
throw new IllegalArgumentException("File MUST NOT be null and MUST exist.");
|
throw new IllegalArgumentException("File MUST NOT be null and MUST exist.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ServiceDiscoveryManager disco = ServiceDiscoveryManager.getInstanceFor(connection());
|
||||||
|
if (!disco.supportsFeature(recipient, getNamespace()) || !disco.supportsFeature(recipient, method.getNamespace())) {
|
||||||
|
throw new SmackException.FeatureNotSupportedException(getNamespace(), recipient);
|
||||||
|
}
|
||||||
|
|
||||||
JingleSession session = jingleManager.createSession(Role.initiator, recipient);
|
JingleSession session = jingleManager.createSession(Role.initiator, recipient);
|
||||||
|
|
||||||
JingleContent content = new JingleContent(JingleContentElement.Creator.initiator, JingleContentElement.Senders.initiator);
|
JingleContent content = new JingleContent(JingleContentElement.Creator.initiator, JingleContentElement.Senders.initiator);
|
||||||
|
@ -90,7 +96,7 @@ public final class JetManager extends Manager implements JingleDescriptionManage
|
||||||
JingleOutgoingFileOffer offer = new JingleOutgoingFileOffer(file);
|
JingleOutgoingFileOffer offer = new JingleOutgoingFileOffer(file);
|
||||||
content.setDescription(offer);
|
content.setDescription(offer);
|
||||||
|
|
||||||
JingleTransportManager transportManager = jingleManager.getBestAvailableTransportManager();
|
JingleTransportManager transportManager = jingleManager.getBestAvailableTransportManager(recipient);
|
||||||
content.setTransport(transportManager.createTransportForInitiator(content));
|
content.setTransport(transportManager.createTransportForInitiator(content));
|
||||||
|
|
||||||
JetSecurity security = new JetSecurity(method, recipient, content.getName(), Aes256GcmNoPadding.NAMESPACE);
|
JetSecurity security = new JetSecurity(method, recipient, content.getName(), Aes256GcmNoPadding.NAMESPACE);
|
||||||
|
|
|
@ -90,12 +90,16 @@ public final class JingleFileTransferManager extends Manager implements JingleDe
|
||||||
|
|
||||||
public OutgoingFileOfferController sendFile(File file, FullJid to)
|
public OutgoingFileOfferController sendFile(File file, FullJid to)
|
||||||
throws SmackException.NotConnectedException, InterruptedException, XMPPException.XMPPErrorException,
|
throws SmackException.NotConnectedException, InterruptedException, XMPPException.XMPPErrorException,
|
||||||
SmackException.NoResponseException {
|
SmackException.NoResponseException, SmackException.FeatureNotSupportedException {
|
||||||
|
|
||||||
if (file == null || !file.exists()) {
|
if (file == null || !file.exists()) {
|
||||||
throw new IllegalArgumentException("File MUST NOT be null and MUST exist.");
|
throw new IllegalArgumentException("File MUST NOT be null and MUST exist.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(to, getNamespace())) {
|
||||||
|
throw new SmackException.FeatureNotSupportedException(getNamespace(), to);
|
||||||
|
}
|
||||||
|
|
||||||
JingleSession session = jingleManager.createSession(Role.initiator, to);
|
JingleSession session = jingleManager.createSession(Role.initiator, to);
|
||||||
|
|
||||||
JingleContent content = new JingleContent(JingleContentElement.Creator.initiator, JingleContentElement.Senders.initiator);
|
JingleContent content = new JingleContent(JingleContentElement.Creator.initiator, JingleContentElement.Senders.initiator);
|
||||||
|
@ -104,7 +108,7 @@ public final class JingleFileTransferManager extends Manager implements JingleDe
|
||||||
JingleOutgoingFileOffer offer = new JingleOutgoingFileOffer(file);
|
JingleOutgoingFileOffer offer = new JingleOutgoingFileOffer(file);
|
||||||
content.setDescription(offer);
|
content.setDescription(offer);
|
||||||
|
|
||||||
JingleTransportManager transportManager = jingleManager.getBestAvailableTransportManager();
|
JingleTransportManager transportManager = jingleManager.getBestAvailableTransportManager(to);
|
||||||
content.setTransport(transportManager.createTransportForInitiator(content));
|
content.setTransport(transportManager.createTransportForInitiator(content));
|
||||||
|
|
||||||
session.initiate(connection());
|
session.initiate(connection());
|
||||||
|
|
|
@ -28,11 +28,14 @@ import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.jivesoftware.smack.Manager;
|
import org.jivesoftware.smack.Manager;
|
||||||
|
import org.jivesoftware.smack.SmackException;
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
|
import org.jivesoftware.smack.XMPPException;
|
||||||
import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler;
|
import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler;
|
||||||
import org.jivesoftware.smack.iqrequest.IQRequestHandler;
|
import org.jivesoftware.smack.iqrequest.IQRequestHandler;
|
||||||
import org.jivesoftware.smack.packet.IQ;
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
import org.jivesoftware.smack.util.StringUtils;
|
import org.jivesoftware.smack.util.StringUtils;
|
||||||
|
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
||||||
import org.jivesoftware.smackx.jingle.adapter.JingleDescriptionAdapter;
|
import org.jivesoftware.smackx.jingle.adapter.JingleDescriptionAdapter;
|
||||||
import org.jivesoftware.smackx.jingle.adapter.JingleSecurityAdapter;
|
import org.jivesoftware.smackx.jingle.adapter.JingleSecurityAdapter;
|
||||||
import org.jivesoftware.smackx.jingle.adapter.JingleTransportAdapter;
|
import org.jivesoftware.smackx.jingle.adapter.JingleTransportAdapter;
|
||||||
|
@ -50,6 +53,7 @@ import org.jivesoftware.smackx.jingle.util.FullJidAndSessionId;
|
||||||
import org.jivesoftware.smackx.jingle.util.Role;
|
import org.jivesoftware.smackx.jingle.util.Role;
|
||||||
|
|
||||||
import org.jxmpp.jid.FullJid;
|
import org.jxmpp.jid.FullJid;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manager for Jingle (XEP-0166).
|
* Manager for Jingle (XEP-0166).
|
||||||
|
@ -213,17 +217,19 @@ public final class JingleManager extends Manager {
|
||||||
return securityManagers.get(namespace);
|
return securityManagers.get(namespace);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<JingleTransportManager> getAvailableTransportManagers() {
|
public List<JingleTransportManager> getAvailableTransportManagers(Jid to) throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException {
|
||||||
return getAvailableTransportManagers(Collections.<String>emptySet());
|
return getAvailableTransportManagers(to, Collections.<String>emptySet());
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<JingleTransportManager> getAvailableTransportManagers(Set<String> except) {
|
public List<JingleTransportManager> getAvailableTransportManagers(Jid to, Set<String> except) throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException {
|
||||||
Set<String> available = new HashSet<>(transportManagers.keySet());
|
Set<String> available = new HashSet<>(transportManagers.keySet());
|
||||||
available.removeAll(except);
|
available.removeAll(except);
|
||||||
List<JingleTransportManager> remaining = new ArrayList<>();
|
List<JingleTransportManager> remaining = new ArrayList<>();
|
||||||
|
|
||||||
for (String namespace : available) {
|
for (String namespace : available) {
|
||||||
remaining.add(transportManagers.get(namespace));
|
if (ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(to, namespace)) {
|
||||||
|
remaining.add(transportManagers.get(namespace));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Collections.sort(remaining, new Comparator<JingleTransportManager>() {
|
Collections.sort(remaining, new Comparator<JingleTransportManager>() {
|
||||||
|
@ -236,12 +242,12 @@ public final class JingleManager extends Manager {
|
||||||
return remaining;
|
return remaining;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JingleTransportManager getBestAvailableTransportManager() {
|
public JingleTransportManager getBestAvailableTransportManager(Jid to) throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException {
|
||||||
return getBestAvailableTransportManager(Collections.<String>emptySet());
|
return getBestAvailableTransportManager(to, Collections.<String>emptySet());
|
||||||
}
|
}
|
||||||
|
|
||||||
public JingleTransportManager getBestAvailableTransportManager(Set<String> except) {
|
public JingleTransportManager getBestAvailableTransportManager(Jid to, Set<String> except) throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException {
|
||||||
List<JingleTransportManager> managers = getAvailableTransportManagers(except);
|
List<JingleTransportManager> managers = getAvailableTransportManagers(to, except);
|
||||||
|
|
||||||
if (managers.size() > 0) {
|
if (managers.size() > 0) {
|
||||||
return managers.get(0);
|
return managers.get(0);
|
||||||
|
|
|
@ -146,7 +146,7 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleContentAccept(JingleElement request, XMPPConnection connection) {
|
public void handleContentAccept(JingleElement request, XMPPConnection connection) {
|
||||||
onAccept(connection);
|
start(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -165,7 +165,7 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
|
||||||
}
|
}
|
||||||
|
|
||||||
getTransport().handleSessionAccept(contentElement.getTransport(), connection);
|
getTransport().handleSessionAccept(contentElement.getTransport(), connection);
|
||||||
onAccept(connection);
|
start(connection);
|
||||||
return IQ.createResultIQ(request);
|
return IQ.createResultIQ(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +198,7 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
|
||||||
transport = pendingReplacingTransport;
|
transport = pendingReplacingTransport;
|
||||||
pendingReplacingTransport = null;
|
pendingReplacingTransport = null;
|
||||||
|
|
||||||
onAccept(connection);
|
start(connection);
|
||||||
|
|
||||||
return IQ.createResultIQ(request);
|
return IQ.createResultIQ(request);
|
||||||
}
|
}
|
||||||
|
@ -285,7 +285,7 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
onAccept(connection);
|
start(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
return IQ.createResultIQ(request);
|
return IQ.createResultIQ(request);
|
||||||
|
@ -384,8 +384,7 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
|
||||||
getSenders() == JingleContentElement.Senders.both;
|
getSenders() == JingleContentElement.Senders.both;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onAccept(final XMPPConnection connection) {
|
public void start(final XMPPConnection connection) {
|
||||||
LOGGER.log(Level.INFO, "Accepted content " + getName());
|
|
||||||
transport.prepare(connection);
|
transport.prepare(connection);
|
||||||
|
|
||||||
if (security != null) {
|
if (security != null) {
|
||||||
|
@ -416,7 +415,7 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTransportReady(BytestreamSession bytestreamSession) {
|
public void onTransportReady(BytestreamSession bytestreamSession) {
|
||||||
LOGGER.log(Level.INFO, "TransportReady: " + (isReceiving() ? "Send" : "Receive"));
|
LOGGER.log(Level.INFO, "TransportReady: " + (isReceiving() ? "Receive" : "Send"));
|
||||||
if (bytestreamSession == null) {
|
if (bytestreamSession == null) {
|
||||||
throw new AssertionError("bytestreamSession MUST NOT be null at this point.");
|
throw new AssertionError("bytestreamSession MUST NOT be null at this point.");
|
||||||
}
|
}
|
||||||
|
@ -469,7 +468,7 @@ public class JingleContent implements JingleTransportCallback, JingleSecurityCal
|
||||||
JingleSession session = getParent();
|
JingleSession session = getParent();
|
||||||
JingleManager jingleManager = session.getJingleManager();
|
JingleManager jingleManager = session.getJingleManager();
|
||||||
|
|
||||||
JingleTransportManager rManager = jingleManager.getBestAvailableTransportManager(blacklist);
|
JingleTransportManager rManager = jingleManager.getBestAvailableTransportManager(getParent().getPeer(), blacklist);
|
||||||
if (rManager == null) {
|
if (rManager == null) {
|
||||||
JingleElement failedTransport = JingleElement.createSessionTerminate(session.getPeer(),
|
JingleElement failedTransport = JingleElement.createSessionTerminate(session.getPeer(),
|
||||||
session.getSessionId(), JingleReasonElement.Reason.failed_transport);
|
session.getSessionId(), JingleReasonElement.Reason.failed_transport);
|
||||||
|
|
|
@ -111,7 +111,7 @@ public class JingleSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (JingleContent content : contents.values()) {
|
for (JingleContent content : contents.values()) {
|
||||||
content.onAccept(connection);
|
content.start(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
connection.createStanzaCollectorAndSend(createSessionAccept()).nextResultOrThrow();
|
connection.createStanzaCollectorAndSend(createSessionAccept()).nextResultOrThrow();
|
||||||
|
|
|
@ -113,10 +113,10 @@ public class JingleS5BTransportCandidate extends JingleTransportCandidate<Jingle
|
||||||
|
|
||||||
case direct:
|
case direct:
|
||||||
if (peersProposal) {
|
if (peersProposal) {
|
||||||
LOGGER.log(Level.INFO, "Connect to foreign direct candidate " + getCandidateId());
|
LOGGER.log(Level.INFO, "Connect to foreign direct candidate " + getCandidateId() + " Address: " + getStreamHost().getAddress() + ":" + getStreamHost().getPort());
|
||||||
this.socket = new Socket(getStreamHost().getAddress(), getStreamHost().getPort());
|
this.socket = new Socket(getStreamHost().getAddress(), getStreamHost().getPort());
|
||||||
} else {
|
} else {
|
||||||
LOGGER.log(Level.INFO, "Connect to our direct candidate " + getCandidateId());
|
LOGGER.log(Level.INFO, "Connect to our direct candidate " + getCandidateId() + " at port " + getStreamHost().getPort());
|
||||||
this.socket = new ServerSocket(getStreamHost().getPort()).accept();
|
this.socket = new ServerSocket(getStreamHost().getPort()).accept();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue