commit 216a41d89666c168a2422e037e93ed82b3f291ec
Author: n8fr8 <nathan(a)freitas.net>
Date: Tue Feb 12 14:05:20 2013 +0700
adding new HS/onion based file sharing service
---
external/Makefile | 30 +++-
external/simple.tar.gz | Bin 0 -> 1083375 bytes
src/org/torproject/android/share/ShareItem.java | 10 ++
src/org/torproject/android/share/ShareService.java | 160 ++++++++++++++++++++
4 files changed, 199 insertions(+), 1 deletion(-)
diff --git a/external/Makefile b/external/Makefile
index 300a465..45bdafa 100644
--- a/external/Makefile
+++ b/external/Makefile
@@ -245,6 +245,33 @@ privoxy-clean:
-rm -rf privoxy
#------------------------------------------------------------------------------#
+# SimpleServer library #
+simple/bin/simple.jar:
+ tar xzvf simple.tar.gz
+ mv simple-* simple
+ test -d simple/bin || mkdir simple/bin
+ cd simple/src && \
+ javac -source 1.6 -target 1.6 org/simpleframework/http/core/ContainerServer.java -d ../bin
+ cd simple/src && \
+ javac -source 1.6 -target 1.6 org/simpleframework/transport/connect/Connection.java -d ../bin
+ cd simple/src && \
+ javac -source 1.6 -target 1.6 org/simpleframework/transport/connect/SocketConnection.java -d ../bin
+ cd simple/bin && \
+ jar cvf simple.jar *
+
+simple-build-stamp: simple/bin/simple.jar
+ touch simple-build-stamp
+
+simple: simple-build-stamp
+ test -d bin || mkdir bin
+ cp simple/bin/simple.jar bin
+
+simple-clean:
+ - rm -f bin/simple.jar
+ - rm -f simple-build-stamp
+ - rm -rf simple
+
+#------------------------------------------------------------------------------#
# JTorControl library
jtorctl/bin/jtorctl.jar:
@@ -270,12 +297,13 @@ jtorctl-clean:
#in order to stop Android OS (older devices) from trying to compress/decompress it
#this is related to a bug in compression of assets and resources > 1MB
-assets: tor privoxy jtorctl obfsproxy
+assets: tor privoxy jtorctl obfsproxy simple
install -d ../res/raw
install -d ../libs
install bin/privoxy ../res/raw
install bin/obfsproxy ../res/raw
install bin/jtorctl.jar ../libs
+ install bin/simple.jar ../libs
cd bin && \
zip ../../res/raw/tor.mp3 tor
diff --git a/external/simple.tar.gz b/external/simple.tar.gz
new file mode 100644
index 0000000..069956b
Binary files /dev/null and b/external/simple.tar.gz differ
diff --git a/src/org/torproject/android/share/ShareItem.java b/src/org/torproject/android/share/ShareItem.java
new file mode 100644
index 0000000..06ec235
--- /dev/null
+++ b/src/org/torproject/android/share/ShareItem.java
@@ -0,0 +1,10 @@
+package org.torproject.android.share;
+
+import android.net.Uri;
+
+public class ShareItem {
+
+ public String mContentType;
+ public long mContentLength;
+ public Uri mUriData;
+}
diff --git a/src/org/torproject/android/share/ShareService.java b/src/org/torproject/android/share/ShareService.java
new file mode 100644
index 0000000..c34fe43
--- /dev/null
+++ b/src/org/torproject/android/share/ShareService.java
@@ -0,0 +1,160 @@
+package org.torproject.android.share;
+
+import java.io.BufferedOutputStream;
+import java.io.InputStream;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.util.HashMap;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
+import org.simpleframework.http.Path;
+import org.simpleframework.http.Request;
+import org.simpleframework.http.Response;
+import org.simpleframework.http.core.Container;
+import org.simpleframework.http.core.ContainerServer;
+import org.simpleframework.transport.Server;
+import org.simpleframework.transport.connect.Connection;
+import org.simpleframework.transport.connect.SocketConnection;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.res.AssetFileDescriptor;
+import android.database.Cursor;
+import android.provider.MediaStore;
+import android.util.Log;
+
+public class ShareService implements Container {
+
+ private final static String TAG = "OrbotShare";
+
+ public static class Task implements Runnable {
+
+ private final Response response;
+ private final Request request;
+
+ public Task(Request request, Response response) {
+ this.response = response;
+ this.request = request;
+ }
+
+ public void run() {
+ try {
+
+ Path path = request.getPath();
+ String rPath = path.toString();
+ if (rPath.length() > 0)
+ rPath = rPath.substring(1);
+
+ ShareItem sItem = sShareItems.get(rPath);
+
+ if (sItem != null)
+ {
+
+ long time = System.currentTimeMillis();
+
+ response.setValue("Server", "OrbotShare/1.0 (Orbot 0.0.12-alpha)");
+ response.setDate("Date", time);
+ response.setDate("Last-Modified", time);
+ response.setValue("Content-Type", sItem.mContentType);
+
+
+ ContentResolver cr = sContext.getContentResolver();
+ InputStream is = cr.openInputStream(sItem.mUriData);
+
+ AssetFileDescriptor fileDesc = cr.openAssetFileDescriptor(sItem.mUriData, "r");
+ fileDesc.getLength();
+
+ response.setValue("Content-Length", fileDesc.getLength()+"");
+
+ String fileName = rPath;
+
+ String scheme = sItem.mUriData.getScheme();
+ if (scheme.equals("file")) {
+ fileName = sItem.mUriData.getLastPathSegment();
+ }
+ else if (scheme.equals("content")) {
+ String[] proj = { MediaStore.Images.Media.TITLE };
+ Cursor cursor = cr.query(sItem.mUriData, proj, null, null, null);
+ if (cursor != null && cursor.getCount() != 0) {
+ int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.TITLE);
+ cursor.moveToFirst();
+ fileName = cursor.getString(columnIndex);
+ }
+ }
+
+ //force file to be downloaded
+ response.setValue("Content-Disposition","attachment; filename=" + fileName);
+
+ BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
+
+ byte[] buffer = new byte[1024];
+ int len = -1;
+ while ( (len = is.read(buffer)) != -1)
+ {
+ bos.write(buffer, 0, len);
+ }
+
+ bos.flush();
+ bos.close();
+ }
+ else
+ {
+ response.setCode(404);
+ response.close();
+ }
+
+ } catch(Exception e) {
+ Log.e(TAG,"error handling request",e);
+ }
+ }
+ }
+
+ public ShareService(int size, Context context) {
+ this.executor = Executors.newFixedThreadPool(size);
+ sContext = context;
+ }
+
+ public void handle(Request request, Response response) {
+ Task task = new Task(request, response);
+
+ executor.execute(task);
+ }
+
+
+ public void startService (int port) throws Exception {
+
+ mServer = new ContainerServer(this);
+ mConnection = new SocketConnection(mServer);
+ SocketAddress address = new InetSocketAddress(port);
+
+ mConnection.connect(address);
+ }
+
+ public void stopService () throws Exception {
+ mConnection.close();
+ }
+
+ public synchronized String addShare (ShareItem sItem)
+ {
+ if (sShareItems == null)
+ {
+ sShareItems = new HashMap<String,ShareItem>();
+
+ }
+
+ String guid = java.util.UUID.randomUUID().toString().substring(0,6);//short guid
+
+ sShareItems.put (guid, sItem);
+
+ return guid;
+ }
+
+ private final Executor executor;
+
+ private Server mServer;
+ private Connection mConnection;
+
+ private static HashMap<String, ShareItem> sShareItems;
+ private static Context sContext;
+}
\ No newline at end of file