Orchid
Orchid copied to clipboard
Some key impl classes have package private constructors without alternatives or ways to construct them (that I can see).
DirectoryStoreFile
and DirectoryStoreImpl
seem to be perfectly sensible default implementations of the classes. They don't have public constructors (is there some other way to get TorClient
up by constructing these indirectly ?).
This is how I am constructing the TorClient (in OSGi). Note: I have copied the classes over into my own package.
import com.subgraph.orchid.*;
import org.apache.felix.dm.annotation.api.Component;
import org.apache.felix.dm.annotation.api.Inject;
import org.apache.felix.dm.annotation.api.Start;
import org.apache.felix.dm.annotation.api.Stop;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import java.io.File;
@Component
public class TorClientComponent {
@Inject
private BundleContext bundleContext;
private ServiceRegistration<TorClient> serviceRegistration = null;
private TorConfig torConfig;
private DirectoryStore directoryStore;
private TorClient torClient;
@Start
public void start() throws Exception {
torConfig = Tor.createConfig();
File torData = bundleContext.getDataFile("torData");
if(torData.exists()) {
if(!torData.isDirectory()) {
throw new Exception("the tor directory should not be a file");
}
}
else {
torData.mkdir();
}
torConfig.setDataDirectory(torData);
directoryStore = new DirectoryStoreImpl(torConfig);
torClient = new TorClient(directoryStore);
torClient.start();
torClient.waitUntilReady(10000);
serviceRegistration = bundleContext.registerService(TorClient.class, torClient, null);
}
@Stop
public void stop() {
torClient.stop();
if(serviceRegistration != null) {
serviceRegistration.unregister();
serviceRegistration = null;
}
}
}
Why not just mimic what is done in TorClient.main(null);
https://github.com/subgraph/Orchid/blob/develop/src/com/subgraph/orchid/TorClient.java#L183
Here is what I did to create a singleton class to wrap the TorClient:
package com.anonyread.util.http;
import com.subgraph.orchid.TorClient;
import com.subgraph.orchid.TorInitializationListener;
import java.net.InetSocketAddress;
import java.net.Proxy;
public class TorClientFactory {
private static final int PROXY_PORT = 9150;
private static final String PROXY_HOST = "localhost";
private static TorClient client;
private static boolean isStarting = false;
private static boolean isRunning = false;
public static TorClient getTorClient(){
return client;
}
public static boolean hasOpenTorTunnel(){
return isStarting || isRunning;
}
public static void openTunnel(){
if(!isRunning){
isStarting = true;
client = new TorClient();
client.enableSocksListener(PROXY_PORT);
client.addInitializationListener(createInitalizationListner());
client.start();
client.enableSocksListener();
}
while(!isRunning){
try{
Thread.sleep(1000l);
} catch(Exception e){
//swallow
}
}
}
public static Proxy getProxy(){
return new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(PROXY_HOST, PROXY_PORT));
}
public static void closeTunnel(){
while(isStarting){
try{
Thread.sleep(100l);
} catch(Exception e){
//swallow
}
}
client.stop();
client = null;
isRunning = false;
isStarting = false;
}
private static TorInitializationListener createInitalizationListner() {
return new TorInitializationListener() {
@Override
public void initializationProgress(String message, int percent) {
System.out.println(">>> [ " + percent + "% ]: " + message);
}
@Override
public void initializationCompleted() {
System.out.println("Tor is ready to go!");
isRunning = true;
isStarting = false;
}
};
}
}