doc
[adBlock.git] / src / de / ub0r / android / adBlock / Proxy.java
blob300bdad732b79cad0dd77ec32a500e30b3d1c2be
1 /**
2 *
3 */
4 package de.ub0r.android.adBlock;
6 import java.io.BufferedReader;
7 import java.io.BufferedWriter;
8 import java.io.IOException;
9 import java.io.InputStreamReader;
10 import java.io.OutputStreamWriter;
11 import java.net.InetSocketAddress;
12 import java.net.ServerSocket;
13 import java.net.Socket;
15 import android.app.Service;
16 import android.content.Context;
17 import android.content.Intent;
18 import android.os.IBinder;
19 import android.widget.Toast;
21 /**
22 * @author flx
24 public class Proxy extends Service implements Runnable {
26 /** Proxy. */
27 private Thread proxy = null;
28 /** Proxy's port. */
29 private int port = 8080;
30 /** Stop proxy? */
31 private boolean stop = false;
33 /**
34 * Class to handle a single proxy connection.
36 * @author flx
38 private class Connection implements Runnable {
40 /** Local Socket. */
41 private final Socket local;
42 /** Remote Socket. */
43 private Socket remote;
44 /** Context in which the app is running. */
45 private final Context cont;
47 /**
48 * Class to Copy a Stream into an other Stream in a Thread.
50 * @author flx
52 private class CopyStream implements Runnable {
53 /** Reader. */
54 private final BufferedReader reader;
55 /** Writer. */
56 private final BufferedWriter writer;
57 /** Object to notify with at EOF. */
58 private final Object sync;
60 /**
61 * Constructor.
63 * @param r
64 * reader
65 * @param w
66 * writer
67 * @param s
68 * object to sync with
70 public CopyStream(final BufferedReader r, final BufferedWriter w,
71 final Object s) {
72 this.reader = r;
73 this.writer = w;
74 this.sync = s;
77 /**
78 * Run by Thread.start().
80 @Override
81 public void run() {
82 try {
83 String s;
84 do {
85 s = this.reader.readLine();
86 if (s == null) {
87 break;
89 this.writer.append(s + "\n");
90 this.writer.flush();
91 } while (true);
92 System.out.println("close remote");
93 synchronized (this.sync) {
94 this.sync.notify();
96 } catch (IOException e) {
97 // handle exception
103 * Constructor.
105 * @param socket
106 * local Socket
107 * @param context
108 * global Context
110 public Connection(final Socket socket, final Context context) {
111 this.local = socket;
112 this.cont = context;
116 * Run by Thread.start().
118 @Override
119 public void run() {
120 try {
121 BufferedReader localReader = new BufferedReader(
122 new InputStreamReader(this.local.getInputStream()));
123 BufferedWriter localWriter = new BufferedWriter(
124 new OutputStreamWriter(this.local.getOutputStream()));
125 BufferedReader remoteReader = null;
126 BufferedWriter remoteWriter = null;
127 StringBuilder buffer = new StringBuilder();
128 String s;
129 while (this.remote == null) {
130 s = localReader.readLine();
131 buffer.append(s + "\n");
132 System.out.println(s);
133 if (s.startsWith("Host:")) {
134 // init remote socket
135 int targetPort = 80;
136 String targetHost = s.substring(6).trim();
137 int i = targetHost.indexOf(':');
138 if (i > 0) {
139 targetPort = Integer.parseInt(targetHost
140 .substring(i + 1));
141 targetHost = targetHost.substring(0, i);
143 System.out.println("connect to " + targetHost + " "
144 + targetPort);
145 this.remote = new Socket();
146 this.remote.connect(new InetSocketAddress(targetHost,
147 targetPort));
148 remoteReader = new BufferedReader(
149 new InputStreamReader(this.remote
150 .getInputStream()));
151 remoteWriter = new BufferedWriter(
152 new OutputStreamWriter(this.remote
153 .getOutputStream()));
154 remoteWriter.append(buffer);
155 remoteWriter.flush();
156 buffer = null;
159 if (this.remote != null && this.remote.isConnected()) {
160 Object sync = new Object();
162 Thread t1 = new Thread(new CopyStream(remoteReader,
163 localWriter, sync));
164 Thread t2 = new Thread(new CopyStream(localReader,
165 remoteWriter, sync));
166 try {
167 synchronized (sync) {
168 t1.start();
169 t2.start();
170 sync.wait();
172 } catch (InterruptedException e) {
173 e.printStackTrace();
175 t1.join();
176 t2.join();
177 this.local.close();
179 } catch (InterruptedException e) {
180 // do nothing
181 } catch (NullPointerException e) {
182 // do nothing
183 } catch (Exception e) {
184 e.printStackTrace();
185 Toast.makeText(this.cont, e.toString(), Toast.LENGTH_LONG)
186 .show();
192 * Default Implementation.
194 * @param intent
195 * called Intent
196 * @return IBinder
197 * @see android.app.Service#onBind(android.content.Intent)
199 @Override
200 public final IBinder onBind(final Intent intent) {
201 return null;
205 * Called on start.
207 * @param intent
208 * Intent called
209 * @param startId
210 * start ID
212 @Override
213 public final void onStart(final Intent intent, final int startId) {
214 super.onStart(intent, startId);
215 if (this.proxy == null) {
216 Toast.makeText(this, "starting proxy..", Toast.LENGTH_LONG).show();
217 this.proxy = new Thread(this);
218 this.proxy.start();
219 } else {
220 Toast.makeText(this, "proxy running", Toast.LENGTH_LONG).show();
225 * Called on destroy.
227 @Override
228 public final void onDestroy() {
229 super.onDestroy();
230 Toast.makeText(this, "stopping proxy..", Toast.LENGTH_LONG).show();
231 this.stop = true;
235 * Run by Thread.start().
237 @Override
238 public final void run() {
239 try {
240 ServerSocket sock = new ServerSocket(this.port);
241 Socket client;
242 while (!this.stop) {
243 client = sock.accept();
244 if (client != null) {
245 Thread t = new Thread(new Connection(client, this));
246 t.start();
249 } catch (IOException e) {
250 e.printStackTrace();
251 Toast.makeText(this, e.toString(), Toast.LENGTH_LONG).show();