00001 using System;
00002 using System.Net;
00003 using System.Threading;
00004 using System.Net.Sockets;
00005 using System.Text;
00006 using System.IO;
00007 using System.Collections;
00008 using Common;
00009
00010 namespace Client {
00014 public class ConnectionManager {
00015 ClientControl clientControl;
00016
00017 public TcpListener listener;
00018 Thread processingThread;
00019
00020
00021 ArrayList connectionList;
00022
00027 public ConnectionManager(ClientControl clientControl) {
00028 this.clientControl = clientControl;
00029 this.listener = new TcpListener(new IPEndPoint(IPAddress.Any, clientControl.settings.ProxyListenPort));
00030
00031 connectionList = new ArrayList();
00032 }
00033
00037 public void Start() {
00038 processingThread = new Thread(new ThreadStart(Run));
00039 listener = new TcpListener(clientControl.settings.ProxyListenIP, clientControl.settings.ProxyListenPort);
00040 processingThread.Start();
00041 }
00042
00047 void Run() {
00048 TcpClient currentClient;
00049 Connection currentConnection;
00050 listener.Start();
00051 try {
00052 while(true) {
00053 currentClient = listener.AcceptTcpClient();
00054
00055 currentConnection = new Connection(currentClient, clientControl.userRequests, connectionList);
00056
00057 ArrayList.Synchronized(connectionList).Add(currentConnection);
00058 currentConnection.Process();
00059 }
00060 } catch (ThreadAbortException) {
00061
00062 }
00063 listener.Stop();
00064 }
00065
00069 public void Stop() {
00070 Console.WriteLine("+++ Stopping Connection Manager +++");
00071 if (processingThread != null && processingThread.IsAlive) {
00072 processingThread.Abort();
00073 }
00074
00075 try {
00076 while (ArrayList.Synchronized(connectionList).Count > 0) {
00077 Connection con = (Connection)connectionList[0];
00078 if (con != null) {
00079 con.Close();
00080 } else {
00081 ArrayList.Synchronized(connectionList).Remove(null);
00082 }
00083 }
00084 foreach (object o in connectionList) {
00085 if (o != null) {
00086 ((Connection)o).Close();
00087 }
00088 }
00089 } catch (Exception ex) {
00090 Console.Error.WriteLine("*** Error closing open connections ***\n{0}", ex);
00091 }
00092 if (processingThread != null) {
00093 processingThread.Join();}
00094 Console.WriteLine("+++ Connection Manager Stopped +++");
00095 }
00096 }
00097
00098
00099 public class Connection {
00100 TcpClient connection;
00101 NetworkStream netStream;
00102 bool haveRequest = false;
00103
00104 Thread processingThread;
00105 ClientHTTPRequestQueueObject currentRequest;
00106 HTTPObjectQueue requestOutputQueue;
00107
00108
00109 ArrayList connections;
00110
00111 public Connection(TcpClient newClient, HTTPObjectQueue requestOutputQueue, ArrayList connections) {
00112 this.connections = connections;
00113 processingThread = new Thread(new ThreadStart(this.Run));
00114 this.connection = newClient;
00115 this.requestOutputQueue = requestOutputQueue;
00116 netStream = connection.GetStream();
00117 }
00118
00122 public void Process() {
00123 processingThread.Start();
00124 }
00125
00126
00130 void Run() {
00131
00132 try {
00133 currentRequest = new ClientHTTPRequestQueueObject(netStream);
00134
00135 haveRequest = true;
00136 currentRequest.connection = this;
00137 requestOutputQueue.EnqueueBlocking(currentRequest);
00138 } catch (Exception ex) {
00139 Console.Error.WriteLine("*** Unable to process connection from browser ***\n{0}", ex);
00140 Close();
00141 }
00142 }
00143
00148 public HTTPRequest Request {
00149 get {
00150 if (haveRequest) { return currentRequest; }
00151 else { throw new ApplicationException("Unable to fetch request on callback - no request stored"); }
00152 }
00153 }
00154
00159 public void SendResponse(HTTPResponse resp) {
00160 try {
00161 byte[] outputBuffer = resp.ToHTTPByteArray();
00162 if (netStream != null && netStream.CanWrite) {
00163 netStream.Write(outputBuffer, 0, outputBuffer.Length);
00164
00165 } else {
00166 throw new ApplicationException("Bad or missing network stream to send response over");
00167 }
00168
00169
00170
00171
00172 } catch (Exception ex) {
00173 Console.Error.WriteLine("*** Unable to write HTTP Response to client, terminating browser connection ***\n{0}", ex);
00174 } finally {
00175 Close();
00176 }
00177 }
00178
00182 public void Close() {
00183 if (netStream != null) { netStream.Close(); }
00184 if (connection != null) { connection.Close(); }
00185 ArrayList.Synchronized(connections).Remove(this);
00186 }
00187
00188 }
00189
00190 }