// enable clients local SOCKS5 proxy on port 7778
SmackConfiguration.setLocalSocks5ProxyEnabled(true);
SmackConfiguration.setLocalSocks5ProxyPort(7778);
// start a local SOCKS5 proxy
Socks5Proxy socks5Proxy = Socks5Proxy.getSocks5Proxy();
socks5Proxy.start();
assertTrue(socks5Proxy.isRunning());
// get Socks5ByteStreamManager for connection
Socks5BytestreamManager byteStreamManager = Socks5BytestreamManager.getBytestreamManager(connection);
/**
* create responses in the order they should be queried specified by the XEP-0065
* specification
*/
// build discover info that supports the SOCKS5 feature
DiscoverInfo discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID);
discoverInfo.addFeature(Socks5BytestreamManager.NAMESPACE);
// return that SOCKS5 is supported if target is queried
protocol.addResponse(discoverInfo, Verification.correspondingSenderReceiver,
Verification.requestTypeGET);
// build discover items containing no proxy item
DiscoverItems discoverItems = Socks5PacketUtils.createDiscoverItems(xmppServer,
initiatorJID);
// return the discover item if XMPP server is queried
protocol.addResponse(discoverItems, Verification.correspondingSenderReceiver,
Verification.requestTypeGET);
// build used stream host response
Bytestream streamHostUsedPacket = Socks5PacketUtils.createBytestreamResponse(targetJID,
initiatorJID);
streamHostUsedPacket.setSessionID(sessionID);
streamHostUsedPacket.setUsedHost(initiatorJID); // local proxy used
// return used stream host info as response to the bytestream initiation
protocol.addResponse(streamHostUsedPacket, new Verification<Bytestream, Bytestream>() {
public void verify(Bytestream request, Bytestream response) {
assertEquals(response.getSessionID(), request.getSessionID());
assertEquals(2, request.getStreamHosts().size());
StreamHost streamHost1 = (StreamHost) request.getStreamHosts().toArray()[0];
assertEquals(response.getUsedHost().getJID(), streamHost1.getJID());
StreamHost streamHost2 = (StreamHost) request.getStreamHosts().toArray()[1];
assertEquals(response.getUsedHost().getJID(), streamHost2.getJID());
assertEquals("localAddress", streamHost2.getAddress());
}
}, Verification.correspondingSenderReceiver, Verification.requestTypeSET);
// create digest to get the socket opened by target
String digest = Socks5Utils.createDigest(sessionID, initiatorJID, targetJID);
// connect to proxy as target
socks5Proxy.addTransfer(digest);
StreamHost streamHost = new StreamHost(targetJID, socks5Proxy.getLocalAddresses().get(0));
streamHost.setPort(socks5Proxy.getPort());
Socks5Client socks5Client = new Socks5Client(streamHost, digest);
InputStream inputStream = socks5Client.getSocket(2000).getInputStream();
// add another network address before establishing SOCKS5 Bytestream
socks5Proxy.addLocalAddress("localAddress");
// finally call the method that should be tested
OutputStream outputStream = byteStreamManager.establishSession(targetJID, sessionID).getOutputStream();
// test the established bytestream
byte[] data = new byte[] { 1, 2, 3 };
outputStream.write(data);
byte[] result = new byte[3];
inputStream.read(result);
assertArrayEquals(data, result);
protocol.verifyAll();
// reset proxy settings
socks5Proxy.stop();
socks5Proxy.removeLocalAddress("localAddress");
SmackConfiguration.setLocalSocks5ProxyPort(7777);
}