Alon Albert
7 years ago
22 changed files with 0 additions and 1088 deletions
@ -1,50 +0,0 @@
@@ -1,50 +0,0 @@
|
||||
package deluge; |
||||
|
||||
import java.io.Closeable; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.io.OutputStream; |
||||
|
||||
public class Util |
||||
{ |
||||
|
||||
public static void close(Closeable closeable) throws IOException |
||||
{ |
||||
if (closeable == null) |
||||
{ |
||||
return; |
||||
} |
||||
closeable.close(); |
||||
} |
||||
|
||||
public static long copy(InputStream from, OutputStream to) throws IOException |
||||
{ |
||||
try |
||||
{ |
||||
try |
||||
{ |
||||
byte[] buf = new byte[4000]; |
||||
long total = 0; |
||||
while (true) |
||||
{ |
||||
int r = from.read(buf); |
||||
if (r == -1) |
||||
{ |
||||
break; |
||||
} |
||||
to.write(buf, 0, r); |
||||
total += r; |
||||
} |
||||
return total; |
||||
} |
||||
finally |
||||
{ |
||||
Util.close(to); |
||||
} |
||||
} |
||||
finally |
||||
{ |
||||
Util.close(from); |
||||
} |
||||
} |
||||
} |
@ -1,30 +0,0 @@
@@ -1,30 +0,0 @@
|
||||
package deluge.api; |
||||
|
||||
public class DelugeException extends Exception |
||||
{ |
||||
private static final long serialVersionUID = 1L; |
||||
|
||||
final public String exceptionType; |
||||
final public String exceptionMsg; |
||||
final public String traceback; |
||||
|
||||
public DelugeException(String type, String msg, String trace) |
||||
{ |
||||
this.exceptionType = type; |
||||
this.exceptionMsg = msg; |
||||
this.traceback = trace; |
||||
} |
||||
|
||||
@Override |
||||
public void printStackTrace() |
||||
{ |
||||
System.err.println(toString()); |
||||
System.err.println(this.traceback); |
||||
} |
||||
|
||||
@Override |
||||
public String toString() |
||||
{ |
||||
return DelugeException.class.getCanonicalName() + " " + this.exceptionType + " (" + this.exceptionMsg + ")"; |
||||
} |
||||
} |
@ -1,78 +0,0 @@
@@ -1,78 +0,0 @@
|
||||
package deluge.api; |
||||
|
||||
import java.util.concurrent.CountDownLatch; |
||||
import java.util.concurrent.ExecutionException; |
||||
import java.util.concurrent.Future; |
||||
import java.util.concurrent.TimeUnit; |
||||
import java.util.concurrent.TimeoutException; |
||||
|
||||
import deluge.impl.AsyncResponse; |
||||
|
||||
public class DelugeFuture<V> extends AsyncResponse<V, DelugeException> implements Future<V> |
||||
{ |
||||
private final CountDownLatch latch = new CountDownLatch(1); |
||||
private V value; |
||||
|
||||
public DelugeFuture() |
||||
{ |
||||
} |
||||
|
||||
public boolean cancel(boolean mayInterruptIfRunning) |
||||
{ |
||||
// TODO Auto-generated method stub
|
||||
return false; |
||||
} |
||||
|
||||
public V get() throws InterruptedException, ExecutionException |
||||
{ |
||||
this.latch.await(); |
||||
return this.value; |
||||
} |
||||
|
||||
public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException |
||||
{ |
||||
if (!this.latch.await(timeout, unit)) |
||||
{ |
||||
throw new TimeoutException(); |
||||
} |
||||
return this.value; |
||||
} |
||||
|
||||
public boolean isCancelled() |
||||
{ |
||||
// TODO Auto-generated method stub
|
||||
return false; |
||||
} |
||||
|
||||
public boolean isDone() |
||||
{ |
||||
return this.value != null; |
||||
} |
||||
|
||||
@Override |
||||
public void onError(DelugeException error) |
||||
{ |
||||
setValue(null); |
||||
super.onError(error); |
||||
} |
||||
|
||||
@Override |
||||
public void onResponse(V response) |
||||
{ |
||||
setValue(response); |
||||
super.onResponse(response); |
||||
} |
||||
|
||||
@Override |
||||
public void onServerError(Exception exception) |
||||
{ |
||||
setValue(null); |
||||
super.onServerError(exception); |
||||
} |
||||
|
||||
public void setValue(V val) |
||||
{ |
||||
this.value = val; |
||||
this.latch.countDown(); |
||||
} |
||||
} |
@ -1,16 +0,0 @@
@@ -1,16 +0,0 @@
|
||||
package deluge.api; |
||||
|
||||
public abstract class ResponseCallback<R, E extends Exception> |
||||
{ |
||||
public void onError(E error) |
||||
{ |
||||
error.printStackTrace(); |
||||
} |
||||
|
||||
public abstract void onResponse(R response); |
||||
|
||||
public void onServerError(Exception exception) |
||||
{ |
||||
exception.printStackTrace(); |
||||
} |
||||
} |
@ -1,20 +0,0 @@
@@ -1,20 +0,0 @@
|
||||
package deluge.api.response; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.List; |
||||
|
||||
import deluge.api.DelugeException; |
||||
|
||||
public class IntegerResponse extends Response |
||||
{ |
||||
|
||||
public IntegerResponse(List<Object> data) throws IOException, DelugeException |
||||
{ |
||||
super(data); |
||||
} |
||||
|
||||
public Integer getReturnValue() |
||||
{ |
||||
return (Integer) this.returnValue.get(2); |
||||
} |
||||
} |
@ -1,62 +0,0 @@
@@ -1,62 +0,0 @@
|
||||
package deluge.api.response; |
||||
|
||||
import java.util.List; |
||||
|
||||
import deluge.api.DelugeException; |
||||
|
||||
public abstract class Response |
||||
{ |
||||
protected List<Object> returnValue; |
||||
|
||||
protected final int RPC_RESPONSE = 1; |
||||
protected final int RPC_ERROR = 2; |
||||
protected final int RPC_EVENT = 3; |
||||
|
||||
public Response(List<Object> decodedObj) throws DelugeException |
||||
{ |
||||
rawData(decodedObj); |
||||
} |
||||
|
||||
public int getMessageType() |
||||
{ |
||||
return (Integer) this.returnValue.get(0); |
||||
} |
||||
|
||||
public int getRequestId() |
||||
{ |
||||
return (Integer) this.returnValue.get(1); |
||||
} |
||||
|
||||
public abstract Object getReturnValue(); |
||||
|
||||
private void process() throws DelugeException |
||||
{ |
||||
if (getMessageType() == this.RPC_ERROR) |
||||
{ |
||||
@SuppressWarnings("unchecked") |
||||
final List<String> params = (List<String>) this.returnValue.get(2); |
||||
final String type = params.get(0); |
||||
final String msg = params.get(1); |
||||
final String trace = params.get(2); |
||||
|
||||
throw new DelugeException(type, msg, trace); |
||||
} |
||||
} |
||||
|
||||
public void rawData(List<Object> decodedObj) throws DelugeException |
||||
{ |
||||
this.returnValue = decodedObj; |
||||
process(); |
||||
} |
||||
|
||||
@Override |
||||
public String toString() |
||||
{ |
||||
String str = "Response { "; |
||||
|
||||
str += this.returnValue.toString(); |
||||
|
||||
str += " }"; |
||||
return str; |
||||
} |
||||
} |
@ -1,6 +0,0 @@
@@ -1,6 +0,0 @@
|
||||
package deluge.api.response; |
||||
|
||||
public enum ReturnType |
||||
{ |
||||
INTEGER, TORRENTS_STATUS |
||||
} |
@ -1,23 +0,0 @@
@@ -1,23 +0,0 @@
|
||||
package deluge.api.response; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
import deluge.api.DelugeException; |
||||
|
||||
public class TorrentsStatusResponse extends Response |
||||
{ |
||||
|
||||
public TorrentsStatusResponse(List<Object> data) throws IOException, DelugeException |
||||
{ |
||||
super(data); |
||||
} |
||||
|
||||
@Override |
||||
@SuppressWarnings("unchecked") |
||||
public Map<String, Map<String, Object>> getReturnValue() |
||||
{ |
||||
return (Map<String, Map<String, Object>>) this.returnValue.get(2); |
||||
} |
||||
} |
@ -1,58 +0,0 @@
@@ -1,58 +0,0 @@
|
||||
package deluge.impl; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
import deluge.api.ResponseCallback; |
||||
|
||||
public class AsyncResponse<R, E extends Exception> extends ResponseCallback<R, E> |
||||
{ |
||||
private final List<ResponseCallback<R, E>> callbacks; |
||||
|
||||
public AsyncResponse() |
||||
{ |
||||
this.callbacks = new ArrayList<ResponseCallback<R, E>>(); |
||||
} |
||||
|
||||
public void addCallback(ResponseCallback<R, E> callback) |
||||
{ |
||||
this.callbacks.add(callback); |
||||
} |
||||
|
||||
@Override |
||||
public void onError(E error) |
||||
{ |
||||
for (final ResponseCallback<R, E> cb : this.callbacks) |
||||
{ |
||||
cb.onError(error); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void onResponse(R response) |
||||
{ |
||||
for (final ResponseCallback<R, E> cb : this.callbacks) |
||||
{ |
||||
cb.onResponse(response); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void onServerError(Exception exception) |
||||
{ |
||||
for (final ResponseCallback<R, E> cb : this.callbacks) |
||||
{ |
||||
cb.onServerError(exception); |
||||
} |
||||
} |
||||
|
||||
public void removeCallback(ResponseCallback<R, E> callback) |
||||
{ |
||||
this.callbacks.remove(callback); |
||||
} |
||||
|
||||
public void then(ResponseCallback<R, E> callback) |
||||
{ |
||||
addCallback(callback); |
||||
} |
||||
} |
@ -1,81 +0,0 @@
@@ -1,81 +0,0 @@
|
||||
package deluge.impl; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.List; |
||||
|
||||
import se.dimovski.rencode.Rencode; |
||||
import deluge.api.DelugeException; |
||||
import deluge.api.DelugeFuture; |
||||
import deluge.api.response.IntegerResponse; |
||||
import deluge.api.response.Response; |
||||
import deluge.api.response.TorrentsStatusResponse; |
||||
import deluge.impl.net.Session.DataCallback; |
||||
|
||||
public class DataHandler implements DataCallback |
||||
{ |
||||
|
||||
@SuppressWarnings("unchecked") |
||||
public void dataRecived(byte[] data) |
||||
{ |
||||
Integer requestId = null; |
||||
List<Object> decodedObj; |
||||
try |
||||
{ |
||||
decodedObj = (List<Object>) Rencode.decode(data); |
||||
requestId = (Integer) decodedObj.get(1); |
||||
|
||||
sendSpecificResponse(requestId, decodedObj); |
||||
} |
||||
catch (final IOException e) |
||||
{ |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
|
||||
@SuppressWarnings("unchecked") |
||||
private void sendSpecificResponse(Integer requestId, List<Object> decodedObj) |
||||
{ |
||||
|
||||
final OngoingRequest req = OngoingRequests.remove(requestId); |
||||
|
||||
try |
||||
{ |
||||
switch (req.getType()) |
||||
{ |
||||
case INTEGER: |
||||
{ |
||||
final DelugeFuture<IntegerResponse> fut = (DelugeFuture<IntegerResponse>) req.getFuture(); |
||||
fut.onResponse(new IntegerResponse(decodedObj)); |
||||
} |
||||
break; |
||||
case TORRENTS_STATUS: |
||||
{ |
||||
final DelugeFuture<TorrentsStatusResponse> fut = (DelugeFuture<TorrentsStatusResponse>) req |
||||
.getFuture(); |
||||
fut.onResponse(new TorrentsStatusResponse(decodedObj)); |
||||
} |
||||
break; |
||||
default: |
||||
{ |
||||
throw new UnsupportedOperationException("Unknown Request: " + req.getType()); |
||||
} |
||||
} |
||||
} |
||||
catch (final DelugeException e) |
||||
{ |
||||
final DelugeFuture<Response> fut = (DelugeFuture<Response>) req.getFuture(); |
||||
fut.onError(e); |
||||
} |
||||
catch (final Exception e) |
||||
{ |
||||
final DelugeFuture<Response> fut = (DelugeFuture<Response>) req.getFuture(); |
||||
fut.onServerError(e); |
||||
} |
||||
} |
||||
|
||||
private void onError() |
||||
{ |
||||
|
||||
} |
||||
|
||||
} |
@ -1,24 +0,0 @@
@@ -1,24 +0,0 @@
|
||||
package deluge.impl; |
||||
|
||||
public class DelugeClient |
||||
{ |
||||
public static DelugeSession getSession(String host) |
||||
{ |
||||
final String[] parts = host.split(":"); |
||||
final int port = parts.length < 2 ? DelugeClient.DEFAULT_PORT : Integer.parseInt(parts[1]); |
||||
return DelugeClient.getSession(parts[0], port); |
||||
} |
||||
|
||||
public static DelugeSession getSession(String host, int port) |
||||
{ |
||||
return DelugeSession.connect(host, port); |
||||
} |
||||
|
||||
public static DelugeSession getSessionDefault() |
||||
{ |
||||
return DelugeClient.getSession("127.0.0.1", DelugeClient.DEFAULT_PORT); |
||||
} |
||||
|
||||
public static final int DEFAULT_PORT = 58846; |
||||
|
||||
} |
@ -1,100 +0,0 @@
@@ -1,100 +0,0 @@
|
||||
package deluge.impl; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
import deluge.api.DelugeFuture; |
||||
import deluge.api.response.IntegerResponse; |
||||
import deluge.api.response.ReturnType; |
||||
import deluge.api.response.TorrentsStatusResponse; |
||||
import deluge.impl.net.Session; |
||||
import deluge.impl.net.TorrentField; |
||||
|
||||
public class DelugeSession |
||||
{ |
||||
public static DelugeSession connect(String host, int port) |
||||
{ |
||||
final Session session = new Session(host, port); |
||||
try |
||||
{ |
||||
session.listen(new DataHandler()); |
||||
} |
||||
catch (final IOException e) |
||||
{ |
||||
e.printStackTrace(); |
||||
} |
||||
return new DelugeSession(session); |
||||
} |
||||
|
||||
private final Session session; |
||||
|
||||
private DelugeSession(Session session) |
||||
|
||||
{ |
||||
this.session = session; |
||||
} |
||||
|
||||
public DelugeFuture<TorrentsStatusResponse> getTorrentsStatus(Map<Object, Object> filter, TorrentField[] fields) |
||||
{ |
||||
final DelugeFuture<TorrentsStatusResponse> future = new DelugeFuture<TorrentsStatusResponse>(); |
||||
final Request request = RequestFactory.getTorrentsStatus(filter, fields); |
||||
send(request, ReturnType.TORRENTS_STATUS, future); |
||||
return future; |
||||
} |
||||
|
||||
public DelugeFuture<IntegerResponse> login(String username, String password) |
||||
{ |
||||
final DelugeFuture<IntegerResponse> future = new DelugeFuture<IntegerResponse>(); |
||||
final Request request = new Request("daemon.login", Util.objects(username, password)); |
||||
send(request, ReturnType.INTEGER, future); |
||||
return future; |
||||
} |
||||
|
||||
public DelugeFuture<IntegerResponse> pauseTorrent(List<String> torrentIds) |
||||
{ |
||||
final DelugeFuture<IntegerResponse> future = new DelugeFuture<IntegerResponse>(); |
||||
final Request request = new Request("core.pause_torrent", Util.objects(torrentIds)); |
||||
send(request, ReturnType.INTEGER, future); |
||||
return future; |
||||
} |
||||
|
||||
public DelugeFuture<IntegerResponse> resumeTorrent(List<String> torrentIds) |
||||
{ |
||||
final DelugeFuture<IntegerResponse> future = new DelugeFuture<IntegerResponse>(); |
||||
final Request request = new Request("core.resume_torrent", Util.objects(torrentIds)); |
||||
send(request, ReturnType.INTEGER, future); |
||||
return future; |
||||
} |
||||
|
||||
public DelugeFuture<IntegerResponse> addTorrentFile(String name, String encodedContents, Map<String, Object> options) |
||||
{ |
||||
final DelugeFuture<IntegerResponse> future = new DelugeFuture<IntegerResponse>(); |
||||
Request request = new Request("core.add_torrent_file", Util.objects(name, encodedContents, options)); |
||||
send(request, ReturnType.INTEGER, future); |
||||
return future; |
||||
} |
||||
|
||||
public DelugeFuture<IntegerResponse> removeTorrent(String torrentId, Boolean removeData) |
||||
{ |
||||
final DelugeFuture<IntegerResponse> future = new DelugeFuture<IntegerResponse>(); |
||||
Request request = new Request("core.remove_torrent", Util.objects(torrentId, removeData)); |
||||
send(request, ReturnType.INTEGER, future); |
||||
return future; |
||||
} |
||||
|
||||
private void send(Request request, ReturnType type, Object future) |
||||
{ |
||||
OngoingRequests.put(request.getRequestId(), type, future); |
||||
|
||||
try |
||||
{ |
||||
this.session.send(request.toByteArray()); |
||||
} |
||||
catch (final IOException e) |
||||
{ |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
|
||||
} |
@ -1,26 +0,0 @@
@@ -1,26 +0,0 @@
|
||||
package deluge.impl; |
||||
|
||||
import deluge.api.response.ReturnType; |
||||
|
||||
public class OngoingRequest |
||||
{ |
||||
private final ReturnType type; |
||||
private final Object future; |
||||
|
||||
public OngoingRequest(ReturnType type, Object future) |
||||
{ |
||||
this.type = type; |
||||
this.future = future; |
||||
} |
||||
|
||||
public Object getFuture() |
||||
{ |
||||
return this.future; |
||||
} |
||||
|
||||
public ReturnType getType() |
||||
{ |
||||
return this.type; |
||||
} |
||||
|
||||
} |
@ -1,23 +0,0 @@
@@ -1,23 +0,0 @@
|
||||
package deluge.impl; |
||||
|
||||
import java.util.Map; |
||||
import java.util.concurrent.ConcurrentHashMap; |
||||
|
||||
import deluge.api.response.ReturnType; |
||||
|
||||
public class OngoingRequests |
||||
{ |
||||
public static void put(int requestId, ReturnType type, Object future) |
||||
{ |
||||
final OngoingRequest ongoing = new OngoingRequest(type, future); |
||||
OngoingRequests.mOngoingRequests.put(requestId, ongoing); |
||||
} |
||||
|
||||
public static OngoingRequest remove(int requestId) |
||||
{ |
||||
return OngoingRequests.mOngoingRequests.remove(requestId); |
||||
} |
||||
|
||||
private static Map<Integer, OngoingRequest> mOngoingRequests = new ConcurrentHashMap<Integer, OngoingRequest>(); |
||||
|
||||
} |
@ -1,56 +0,0 @@
@@ -1,56 +0,0 @@
|
||||
package deluge.impl; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
import java.util.concurrent.atomic.AtomicInteger; |
||||
|
||||
import se.dimovski.rencode.Rencode; |
||||
|
||||
public class Request |
||||
{ |
||||
private static AtomicInteger requestCounter = new AtomicInteger(); |
||||
|
||||
private final Integer requestId; |
||||
private final String method; |
||||
private final Object[] args; |
||||
private final Map<Object, Object> kwargs; |
||||
|
||||
public Request(String method) |
||||
{ |
||||
this(method, new Object[0]); |
||||
} |
||||
|
||||
public Request(String method, Object[] args) |
||||
{ |
||||
this(method, args, new HashMap<Object, Object>()); |
||||
} |
||||
|
||||
public Request(String method, Object[] args, Map<Object, Object> kwargs) |
||||
{ |
||||
this.requestId = Request.requestCounter.getAndIncrement(); |
||||
this.method = method; |
||||
this.args = args; |
||||
this.kwargs = kwargs; |
||||
} |
||||
|
||||
public Integer getRequestId() |
||||
{ |
||||
return this.requestId; |
||||
} |
||||
|
||||
public byte[] toByteArray() |
||||
{ |
||||
final Object obj = new Object[] { new Object[] { this.requestId, this.method, this.args, this.kwargs } }; |
||||
try |
||||
{ |
||||
return Rencode.encode(obj); |
||||
} |
||||
catch (final IOException e) |
||||
{ |
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace(); |
||||
} |
||||
return null; |
||||
} |
||||
} |
@ -1,44 +0,0 @@
@@ -1,44 +0,0 @@
|
||||
package deluge.impl; |
||||
|
||||
import java.util.Map; |
||||
|
||||
import deluge.impl.net.TorrentField; |
||||
|
||||
public class RequestFactory |
||||
{ |
||||
|
||||
public static Request getSessionState() |
||||
{ |
||||
return new Request("core.get_session_state"); |
||||
} |
||||
|
||||
public static Request getTorrentsStatus() |
||||
{ |
||||
return RequestFactory.getTorrentsStatus(null, null); |
||||
} |
||||
|
||||
public static Request getTorrentsStatus(Map<Object, Object> filter) |
||||
{ |
||||
return RequestFactory.getTorrentsStatus(filter, null); |
||||
} |
||||
|
||||
public static Request getTorrentsStatus(Map<Object, Object> filter, TorrentField[] fields) |
||||
{ |
||||
Object[] fieldNames = new Object[0]; |
||||
if (fields != null) |
||||
{ |
||||
fieldNames = new Object[fields.length]; |
||||
for (int i = 0; i < fields.length; i++) |
||||
{ |
||||
fieldNames[i] = fields[i].toString(); |
||||
} |
||||
} |
||||
|
||||
return new Request("core.get_torrents_status", Util.objects(filter, fieldNames)); |
||||
} |
||||
|
||||
public static Request getTorrentsStatus(TorrentField[] fields) |
||||
{ |
||||
return RequestFactory.getTorrentsStatus(null, null); |
||||
} |
||||
} |
@ -1,16 +0,0 @@
@@ -1,16 +0,0 @@
|
||||
package deluge.impl; |
||||
|
||||
import deluge.impl.net.TorrentField; |
||||
|
||||
public class Util |
||||
{ |
||||
public static TorrentField[] fields(TorrentField... fields) |
||||
{ |
||||
return fields; |
||||
} |
||||
|
||||
public static Object[] objects(Object... objects) |
||||
{ |
||||
return objects; |
||||
} |
||||
} |
@ -1,23 +0,0 @@
@@ -1,23 +0,0 @@
|
||||
package deluge.impl.net; |
||||
|
||||
import java.security.cert.CertificateException; |
||||
import java.security.cert.X509Certificate; |
||||
|
||||
import javax.net.ssl.X509TrustManager; |
||||
|
||||
public class AcceptAllTrustManager implements X509TrustManager |
||||
{ |
||||
|
||||
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException |
||||
{ |
||||
} |
||||
|
||||
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException |
||||
{ |
||||
} |
||||
|
||||
public X509Certificate[] getAcceptedIssuers() |
||||
{ |
||||
return null; |
||||
} |
||||
} |
@ -1,32 +0,0 @@
@@ -1,32 +0,0 @@
|
||||
package deluge.impl.net; |
||||
|
||||
import java.util.concurrent.ExecutorService; |
||||
import java.util.concurrent.Executors; |
||||
|
||||
public class ResponseExecutor |
||||
{ |
||||
|
||||
ExecutorService mExecutor; |
||||
|
||||
public ResponseExecutor() |
||||
{ |
||||
this.mExecutor = Executors.newFixedThreadPool(20); |
||||
} |
||||
|
||||
public void execute(Runnable task) |
||||
{ |
||||
this.mExecutor.execute(task); |
||||
} |
||||
|
||||
public void shutdown() |
||||
{ |
||||
if (this.mExecutor != null) |
||||
{ |
||||
this.mExecutor.shutdown(); |
||||
while (!this.mExecutor.isTerminated()) |
||||
{ |
||||
} |
||||
System.out.println("Finished all threads"); |
||||
} |
||||
} |
||||
} |
@ -1,41 +0,0 @@
@@ -1,41 +0,0 @@
|
||||
package deluge.impl.net; |
||||
|
||||
import java.io.IOException; |
||||
import java.net.UnknownHostException; |
||||
import java.security.KeyManagementException; |
||||
import java.security.NoSuchAlgorithmException; |
||||
|
||||
import javax.net.ssl.HandshakeCompletedEvent; |
||||
import javax.net.ssl.HandshakeCompletedListener; |
||||
import javax.net.ssl.SSLContext; |
||||
import javax.net.ssl.SSLSocket; |
||||
import javax.net.ssl.TrustManager; |
||||
|
||||
public class SSL3Socket |
||||
{ |
||||
|
||||
public static SSLSocket createSSLv3Socket(String address, int port) throws KeyManagementException, |
||||
UnknownHostException, IOException, NoSuchAlgorithmException |
||||
{ |
||||
final TrustManager[] trustAllCerts = new TrustManager[] { new AcceptAllTrustManager() }; |
||||
|
||||
final SSLContext sc = SSLContext.getInstance("SSLv3"); |
||||
sc.init(null, trustAllCerts, new java.security.SecureRandom()); |
||||
|
||||
final SSLSocket mySocket = (SSLSocket) sc.getSocketFactory().createSocket(address, port); |
||||
|
||||
final String[] protocols = { "SSLv3", "TLSv1" }; |
||||
mySocket.setEnabledProtocols(protocols); |
||||
|
||||
mySocket.addHandshakeCompletedListener(new HandshakeCompletedListener() |
||||
{ |
||||
|
||||
public void handshakeCompleted(HandshakeCompletedEvent event) |
||||
{ |
||||
System.out.println("Handshake complete"); |
||||
} |
||||
}); |
||||
|
||||
return mySocket; |
||||
} |
||||
} |
@ -1,245 +0,0 @@
@@ -1,245 +0,0 @@
|
||||
package deluge.impl.net; |
||||
|
||||
import java.io.BufferedInputStream; |
||||
import java.io.BufferedOutputStream; |
||||
import java.io.ByteArrayInputStream; |
||||
import java.io.ByteArrayOutputStream; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.io.OutputStream; |
||||
import java.io.UnsupportedEncodingException; |
||||
import java.util.concurrent.ArrayBlockingQueue; |
||||
import java.util.concurrent.BlockingQueue; |
||||
import java.util.concurrent.CountDownLatch; |
||||
import java.util.concurrent.TimeUnit; |
||||
import java.util.zip.DataFormatException; |
||||
import java.util.zip.Deflater; |
||||
import java.util.zip.DeflaterOutputStream; |
||||
import java.util.zip.Inflater; |
||||
import java.util.zip.InflaterInputStream; |
||||
|
||||
import javax.net.ssl.SSLSocket; |
||||
|
||||
import deluge.Util; |
||||
|
||||
public class Session |
||||
{ |
||||
public interface DataCallback |
||||
{ |
||||
public void dataRecived(byte[] data); |
||||
} |
||||
|
||||
public static byte[] decompressByteArray(byte[] data) throws IOException |
||||
{ |
||||
final InputStream from = new InflaterInputStream(new ByteArrayInputStream(data)); |
||||
final ByteArrayOutputStream to = new ByteArrayOutputStream(); |
||||
Util.copy(from, to); |
||||
byte[] output = to.toByteArray(); |
||||
from.close(); |
||||
to.close(); |
||||
return output; |
||||
} |
||||
|
||||
private static byte[] decompress(byte[] input) throws DataFormatException |
||||
{ |
||||
final ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
||||
|
||||
final Inflater decompresser = new Inflater(false); |
||||
|
||||
decompresser.setInput(input, 0, input.length); |
||||
final byte[] result = new byte[1024]; |
||||
while (!decompresser.finished()) |
||||
{ |
||||
final int resultLength = decompresser.inflate(result); |
||||
baos.write(result, 0, resultLength); |
||||
} |
||||
decompresser.end(); |
||||
|
||||
final byte[] returnValue = baos.toByteArray(); |
||||
try |
||||
{ |
||||
baos.close(); |
||||
} |
||||
catch (final IOException e) |
||||
{ |
||||
} |
||||
return returnValue; |
||||
} |
||||
|
||||
private final BlockingQueue<byte[]> queue = new ArrayBlockingQueue<byte[]>(50); |
||||
private SSLSocket mySocket; |
||||
String myAddress; |
||||
int myPort; |
||||
Thread sender = null; |
||||
|
||||
public final CountDownLatch latch = new CountDownLatch(1); |
||||
|
||||
public Session(String address, int port) |
||||
{ |
||||
this.myAddress = address; |
||||
this.myPort = port; |
||||
} |
||||
|
||||
public byte[] compress(byte[] data) throws IOException |
||||
{ |
||||
|
||||
final ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
||||
|
||||
final Deflater d = new Deflater(); |
||||
final DeflaterOutputStream dout = new DeflaterOutputStream(baos, d); |
||||
dout.write(data); |
||||
dout.close(); |
||||
|
||||
final byte[] output = baos.toByteArray(); |
||||
baos.close(); |
||||
return output; |
||||
} |
||||
|
||||
private void createSocket() |
||||
{ |
||||
if (this.mySocket == null) |
||||
{ |
||||
try |
||||
{ |
||||
this.mySocket = SSL3Socket.createSSLv3Socket(this.myAddress, this.myPort); |
||||
this.mySocket.startHandshake(); |
||||
} |
||||
catch (final Exception e1) |
||||
{ |
||||
e1.printStackTrace(); |
||||
this.mySocket = null; |
||||
} |
||||
} |
||||
this.latch.countDown(); |
||||
} |
||||
|
||||
public void listen(final DataCallback cb) throws IOException |
||||
{ |
||||
new Thread(new Runnable() |
||||
{ |
||||
|
||||
public void run() |
||||
{ |
||||
createSocket(); |
||||
System.out.println("Listening Thread started"); |
||||
try |
||||
{ |
||||
while (Session.this.mySocket != null) |
||||
{ |
||||
|
||||
final InputStream inputStream = new BufferedInputStream(Session.this.mySocket.getInputStream()); |
||||
|
||||
final ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
||||
|
||||
int bytesRead; |
||||
final byte[] buffer = new byte[1024]; |
||||
while ((bytesRead = inputStream.read(buffer)) != -1) |
||||
{ |
||||
baos.write(buffer); |
||||
|
||||
if (bytesRead < 1024) |
||||
{ |
||||
final byte[] unpacked = Session.decompressByteArray(baos.toByteArray()); |
||||
baos.reset(); |
||||
cb.dataRecived(unpacked); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
catch (final UnsupportedEncodingException e) |
||||
{ |
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace(); |
||||
} |
||||
catch (final IOException e) |
||||
{ |
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace(); |
||||
} |
||||
|
||||
} |
||||
}).start(); |
||||
|
||||
try |
||||
{ |
||||
this.latch.await(3, TimeUnit.SECONDS); |
||||
} |
||||
catch (final InterruptedException e) |
||||
{ |
||||
} |
||||
if (this.mySocket == null) |
||||
{ |
||||
throw new IOException(); |
||||
} |
||||
} |
||||
|
||||
public void send(byte[] request) throws IOException |
||||
{ |
||||
if (this.sender == null) |
||||
{ |
||||
sender(); |
||||
} |
||||
try |
||||
{ |
||||
this.queue.put(request); |
||||
} |
||||
catch (final InterruptedException e) |
||||
{ |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
|
||||
public void sender() throws IOException |
||||
{ |
||||
this.sender = new Thread(new Runnable() |
||||
{ |
||||
|
||||
public void run() |
||||
{ |
||||
createSocket(); |
||||
System.out.println("Sending Thread started"); |
||||
try |
||||
{ |
||||
while (Session.this.mySocket != null) |
||||
{ |
||||
byte[] packedData; |
||||
try |
||||
{ |
||||
final byte[] x = Session.this.queue.take(); |
||||
packedData = compress(x); |
||||
|
||||
final OutputStream out = new BufferedOutputStream(Session.this.mySocket.getOutputStream()); |
||||
out.write(packedData); |
||||
out.flush(); |
||||
} |
||||
catch (final InterruptedException e) |
||||
{ |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
|
||||
} |
||||
catch (final IOException e) |
||||
{ |
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace(); |
||||
} |
||||
|
||||
} |
||||
}); |
||||
this.sender.start(); |
||||
|
||||
try |
||||
{ |
||||
this.latch.await(3, TimeUnit.SECONDS); |
||||
} |
||||
catch (final InterruptedException e) |
||||
{ |
||||
} |
||||
if (this.mySocket == null) |
||||
{ |
||||
throw new IOException(); |
||||
} |
||||
} |
||||
|
||||
} |
@ -1,34 +0,0 @@
@@ -1,34 +0,0 @@
|
||||
package deluge.impl.net; |
||||
|
||||
public enum TorrentField |
||||
{ |
||||
ACTIVE_TIME("active_time"), ALL_TIME_DOWNLOAD("all_time_download"), COMPACT("compact"), DISTRIBUTED_COPIES( |
||||
"distributed_copies"), DOWNLOAD_PAYLOAD_RATE("download_payload_rate"), FILE_PRIORITIES("file_priorities"), HASH( |
||||
"hash"), IS_AUTO_MANAGED("is_auto_managed"), IS_FINISHED("is_finished"), MAX_CONNECTIONS("max_connections"), MAX_DOWNLOAD_SPEED( |
||||
"max_download_speed"), MAX_UPLOAD_SLOTS("max_upload_slots"), MAX_UPLOAD_SPEED("max_upload_speed"), MESSAGE( |
||||
"message"), MOVE_ON_COMPLETED_PATH("move_on_completed_path"), MOVE_ON_COMPLETED("move_on_completed"), MOVE_COMPLETED_PATH( |
||||
"move_completed_path"), MOVE_COMPLETED("move_completed"), NEXT_ANNOUNCE("next_announce"), NUM_PEERS( |
||||
"num_peers"), NUM_SEEDS("num_seeds"), PAUSED("paused"), PRIORITIZE_FIRST_LAST("prioritize_first_last"), PROGRESS( |
||||
"progress"), REMOVE_AT_RATIO("remove_at_ratio"), SAVE_PATH("save_path"), SEEDING_TIME("seeding_time"), SEEDS_PEERS_RATIO( |
||||
"seeds_peers_ratio"), SEED_RANK("seed_rank"), STATE("state"), STOP_AT_RATIO("stop_at_ratio"), STOP_RATIO( |
||||
"stop_ratio"), TIME_ADDED("time_added"), TOTAL_DONE("total_done"), TOTAL_PAYLOAD_DOWNLOAD( |
||||
"total_payload_download"), TOTAL_PAYLOAD_UPLOAD("total_payload_upload"), TOTAL_PEERS("total_peers"), TOTAL_SEEDS( |
||||
"total_seeds"), TOTAL_UPLOADED("total_uploaded"), TOTAL_WANTED("total_wanted"), TRACKER("tracker"), TRACKERS( |
||||
"trackers"), TRACKER_STATUS("tracker_status"), UPLOAD_PAYLOAD_RATE("upload_payload_rate"), COMMENT( |
||||
"comment"), ETA("eta"), FILE_PROGRESS("file_progress"), FILES("files"), IS_SEED("is_seed"), NAME("name"), NUM_FILES( |
||||
"num_files"), NUM_PIECES("num_pieces"), PEERS("peers"), PIECE_LENGTH("piece_length"), PRIVATE("private"), QUEUE( |
||||
"queue"), RATIO("ratio"), TOTAL_SIZE("total_size"), TRACKER_HOST("tracker_host"), LABEL("label"); |
||||
|
||||
private final String value; |
||||
|
||||
TorrentField(String str) |
||||
{ |
||||
this.value = str; |
||||
} |
||||
|
||||
@Override |
||||
public String toString() |
||||
{ |
||||
return this.value; |
||||
} |
||||
} |
Loading…
Reference in new issue