ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/proxy/Client.cs
Revision: 1.1
Committed: Mon Nov 5 20:08:44 2012 UTC (11 years, 7 months ago) by sf-demisephi
Branch: MAIN
CVS Tags: HEAD
Log Message:
added proxy to repository

File Contents

# User Rev Content
1 sf-demisephi 1.1
2     using System;
3     using System.Linq;
4     using System.IO;
5     using System.Net;
6     using System.Text;
7     using System.Net.Sockets;
8     using System.Threading;
9     using System.Collections;
10     using System.Collections.Generic;
11     using System.Security.Cryptography;
12     using System.Runtime.Serialization.Formatters.Binary;
13     using System.Text.RegularExpressions;
14    
15     namespace _olbaid_websockets
16     {
17    
18     class UnPack {
19    
20     byte [] buffer;
21     public int position;
22    
23     public UnPack(byte[] b){
24     buffer = b;
25     position = 0;
26     }
27    
28     public uint w (){
29     uint num = 0;
30     byte bite = 0;
31     do {
32     num*=128;
33     bite = buffer[position++];
34     num+=(uint)(bite&0x7f);
35     }while ((bite&0x80)>0);
36     return num;
37     }
38     }
39     class Client
40     {
41     private Socket client;
42     private Thread thread;
43     private Socket deliantraClient = null;
44     private bool upgraded = false;
45     private bool mask = true;
46     private bool useHixie = false;
47    
48     Random r = new Random();
49    
50     System.Text.UTF8Encoding encodingUTF8 = new System.Text.UTF8Encoding();
51    
52    
53     private byte[] buffer = new byte[4096*16];
54     private byte[] mergedBuffer = new byte[4096*32];
55     private int mergedBufferLength = 0;
56    
57     public bool IsBitSet(byte b, int pos) {
58     return (b & (int)Math.Pow(2, pos)) > 0 ? true : false;
59     }
60    
61     public static int getNSpaces (string s){
62     return (new String(s.Where( c=> c==' ').ToArray())).Length;
63     }
64    
65     public static Int64 numbers(string s){
66     char[] nums = s.Where( c => Char.IsNumber(c)).ToArray();
67     Int64 ret = Int64.Parse(new String(nums));
68     return ret;
69     }
70    
71     public static void setBytes(byte [] buffer,UInt16 val,int index){
72     for (int i=0;i<2;++i){
73     byte b = (byte)((val >> (3-i)*8)&0xff);
74     buffer[index+i] = b;
75     }
76     }
77    
78     public static void setBytes(byte [] buffer,UInt32 val,int index){
79     for (int i=0;i<4;++i){
80     byte b = (byte)((val >> (3-i)*8)&0xff);
81     buffer[index+i] = b;
82     }
83     }
84    
85     public static void setBytesR(byte [] buffer,UInt16 val,int index){
86     for (int i=1;i>=0;--i){
87     byte b = (byte)((val >> (3-i)*8)&0xff);
88     buffer[index+i] = b;
89     }
90     }
91    
92     public static byte [] calcHixieResponse (string key1,string key2,byte [] l8b){
93     UInt64 numbers1 = (UInt64) numbers(key1);
94     UInt64 numbers2 = (UInt64) numbers(key2);
95     UInt64 spaces1 = (ulong)getNSpaces(key1);
96     UInt64 spaces2 = (ulong)getNSpaces(key2);
97     byte [] key = new byte [16];
98    
99     Array.Clear(key,0,16);
100    
101     setBytes(key,(UInt32)(((numbers1/spaces1))),0);
102     setBytes(key,(UInt32)(((numbers2/spaces2))),4);
103    
104     Array.Copy(l8b,0,key,8,8);
105     MD5 md5Hash = MD5.Create();
106     return md5Hash.ComputeHash(key);
107     }
108    
109     public static void setBytesR(byte [] buffer,UInt32 val,int index){
110     for (int i=3;i>=0;--i){
111     byte b = (byte)((val >> (3-i)*8)&0xff);
112     buffer[index+i] = b;
113     }
114     }
115     public void onReceivedClientData (IAsyncResult asyn){
116    
117     Socket mySocket = (Socket)asyn.AsyncState;
118    
119     int bytesRead = mySocket.EndReceive(asyn);
120     if (bytesRead==0){
121     Console.WriteLine ("Connection closed by socket {0}" , mySocket==client?" client " : " deliantra ");
122    
123     mySocket.Close();
124    
125     if ((mySocket==client)&&(deliantraClient!=null)){
126     client = null;
127     Console.WriteLine ("trying to close deliantraClient");
128     try {
129     deliantraClient.Close();
130     deliantraClient = null;
131     }catch (Exception ex){
132    
133     }
134     }
135     return;
136     }
137    
138    
139     if (mySocket == client){
140     //deliantraClient.Send(buffer,bytesRead,0);
141     Hashtable request = new Hashtable();
142    
143     if (upgraded == false){
144     dump(buffer,bytesRead);
145     string incoming = encodingUTF8.GetString(buffer,0,bytesRead);
146    
147     Console.WriteLine (incoming);
148    
149     string [] lines = incoming.Split(new string [] {"\n"},StringSplitOptions.RemoveEmptyEntries);
150    
151     for (int i = 1;i<lines.Length;++i){
152     string [] line = lines[i].Split(new string [] {": "},StringSplitOptions.RemoveEmptyEntries);
153     if (line.Length>=3)
154     request.Add(line[0].ToString().ToLower().Trim(),line[1] + ":" + line[2]);
155     else if (line.Length>=2)
156     request.Add(line[0].ToString().ToLower().Trim(),line[1]);
157    
158     }
159     foreach (DictionaryEntry e in request){
160     Console.WriteLine(e.Key.ToString() + " : '" + e.Value.ToString() + "'");
161     }
162    
163    
164     if (request["sec-websocket-key1"]!=null){
165     string key1 = "357184 636 L0";
166     key1 = request["sec-websocket-key1"].ToString().Trim();
167    
168     string key2 = "U 4=> 9&6= 52OeA[8 #880";
169     key2 = request["sec-websocket-key2"].ToString().Trim();
170     byte [] l8b = new byte[8];
171     Array.Copy (buffer,bytesRead-8,l8b,0,8);
172    
173     dump(l8b,8);
174    
175     byte [] hixiResp = calcHixieResponse(key1,key2,l8b);
176    
177     string origin = (string) (request["origin"] != null ? request["origin"].ToString().Trim(): "");
178     //origin="http://localhost";
179     string host = (string) (request["host"] != null ? request["host"].ToString().Trim (): "");
180     string location = Regex.Match(incoming,@"(/[a-z]+)",RegexOptions.IgnoreCase).Value.ToString();
181    
182     StringBuilder bResponse = new StringBuilder();
183     bResponse.Append("HTTP/1.1 101 WebSocket Protocol Handshake\r\n");
184     bResponse.Append( "Upgrade: WebSocket\r\n");
185     bResponse.Append("Connection: Upgrade\r\n");
186     bResponse.AppendFormat("Sec-WebSocket-Origin: {0}\r\n",origin);
187     bResponse.Append( "Sec-WebSocket-Protocol: chat\r\n");
188     bResponse.AppendFormat("Sec-WebSocket-Location: ws://{0}{1}\r\n\r\n",host,location);
189     byte [] data = encodingUTF8.GetBytes(bResponse.ToString());
190     byte [] result = new byte[data.Length+hixiResp.Length];
191     Array.Copy(data,0,result,0,data.Length);
192     Array.Copy(hixiResp,0,result,data.Length,hixiResp.Length);
193     client.Send(result,result.Length,SocketFlags.None);
194     useHixie = true;
195     upgraded = true;
196     }else{
197     string key = "";
198     if (request["sec-websocket-key"]!=null){
199     Console.WriteLine("Key: " + request["sec-websocket-key"].ToString());
200     key = request["sec-websocket-key"].ToString().Trim();
201     }else{
202     key = "";
203     }
204     if (request["sec-websocket-extensions"]!=null){
205     mask = false;
206     }
207     Console.WriteLine(key);
208     //key+=Guid.NewGuid().ToString();
209     key+="258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
210     Console.WriteLine(key);
211     SHA1 sha = new SHA1CryptoServiceProvider();
212     byte [] hash = sha.ComputeHash(encoding.GetBytes(key));
213    
214     key = EncodeTo64(hash);
215     Console.WriteLine(key);
216     string response = "HTTP/1.1 101 Switching Protocols\n"
217     + "Upgrade: websocket\n"
218     + "Connection: Upgrade\n"
219     //+ "Sec-WebSocket-Protocol: chat\r\n"
220     + "Sec-WebSocket-Accept: " + key +"\n\n";
221     response = "HTTP/1.1 101 WebSocket Protocol Handshake\r\n"
222     + "Upgrade: WebSocket\r\n"
223     + "Connection: Upgrade\r\n"
224     + "Sec-WebSocket-Accept: " +key + "\r\n\r\n";
225     client.Send(encoding.GetBytes(response));
226     upgraded = true;
227     }
228    
229     deliantraClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
230     deliantraClient.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
231     IPEndPoint ipLocal = new IPEndPoint(IPAddress.Parse("194.126.175.156"), 13327);
232     deliantraClient.Connect(ipLocal);
233     deliantraClient.BeginReceive(buffer, 0, 4096, 0, new AsyncCallback(onReceivedClientData),deliantraClient);
234    
235     }else{
236     //dump (buffer,bytesRead);
237    
238     String msg = receiveMessage(buffer,bytesRead);
239     Console.WriteLine(msg);
240     Array.Copy(encodingUTF8.GetBytes(msg),0,buffer,2,bytesRead = encodingUTF8.GetBytes(msg).Length);
241     buffer [0] = (byte)(bytesRead/256);
242     buffer [1] = (byte)(bytesRead%256);
243     deliantraClient.Send(buffer,0,bytesRead+2,0);
244     //Console.WriteLine(encoding.GetString(unmaskedData,0,payloadLen));
245    
246     //sendMessage("HELLO CRUEL WORLD");
247    
248     }
249    
250     }else{
251     //client.Send(buffer,bytesRead,0);
252     //dump (buffer,bytesRead);
253     if (client == null){
254     deliantraClient.Close();
255     deliantraClient = null;
256     return;
257     }
258     Array.Copy ( buffer,0,mergedBuffer,mergedBufferLength,bytesRead);
259     mergedBufferLength += bytesRead;
260    
261     int index = 0;
262     int len;
263     byte [] tmpBuffer;
264     while (index<mergedBufferLength){
265     try {
266     len = mergedBuffer[index++]*256 + mergedBuffer[index++];
267     //Console.WriteLine("Index : {0}, len : {1}, mergedBufferLength {2}",index,len,mergedBufferLength);
268    
269     if ((len+index)<=mergedBufferLength){
270     //Console.WriteLine("Sending {0}",encodingUTF8.GetString(mergedBuffer,index,len));
271     //sendMessage(encodingUTF8.GetString(mergedBuffer,index,len));
272     tmpBuffer = new byte [len];
273     Array.Copy(mergedBuffer,index,tmpBuffer,0,len);
274     if (encoding.GetString(tmpBuffer,0,2).Equals("ix")){
275     StringBuilder sb = new StringBuilder();
276     UnPack up = new UnPack(tmpBuffer);
277     up.position = 3;
278     uint id = up.w();
279     up.w();
280     sb.Append(id);
281     sb.Append(".png");
282    
283     if (!File.Exists("/var/www/olbaid/faces/" + sb.ToString())){
284     BinaryWriter bw = new BinaryWriter(File.OpenWrite("/var/www/olbaid/faces/" + sb.ToString()));
285     bw.Write(tmpBuffer,up.position,len-up.position);
286     bw.Close();
287     }
288     tmpBuffer = new byte [up.position+3];
289     Array.Copy(mergedBuffer,index,tmpBuffer,0,3+up.position);
290    
291     }
292     sendMessage(EncodeTo64(tmpBuffer));
293    
294     Array.Copy(mergedBuffer,index+len,mergedBuffer,0,mergedBufferLength-len-2);
295     mergedBufferLength -= len + 2;
296     index = 0;
297     }else{
298     break;
299     }
300     }catch (Exception ex){
301     }
302    
303     }
304    
305     }
306     mySocket.BeginReceive(buffer, 0, 4096, 0, new AsyncCallback(onReceivedClientData),mySocket);
307     }
308    
309    
310     public string receiveMessage(byte[] buffer,int bytesRead){
311    
312    
313     if (useHixie){
314     string ret = encodingUTF8.GetString(buffer,1,bytesRead-2);
315     Console.WriteLine(ret);
316     return ret;
317     }
318     UInt64 payloadLen = 0;
319    
320     //int opcode = buffer[0]&0xf;
321    
322    
323     bool mask = IsBitSet(buffer[1],7);
324     if (!mask){
325     //Console.WriteLine("Ignoring non masked message");
326     //return;
327     }
328    
329    
330     payloadLen = (ulong)(buffer[1]& ~128);
331    
332     if (payloadLen==125){
333    
334     }else if (payloadLen==126){
335     payloadLen = (ulong)(buffer[2]*256 + buffer[3]);
336     Array.Copy(buffer,4,buffer,2,bytesRead-2);
337     }else if (payloadLen==127){
338     payloadLen = (ulong)(buffer[2]*256*256*256 + buffer[3]*256*256 + buffer[4]*256 + buffer[5]);
339     Array.Copy(buffer,6,buffer,2,bytesRead-2);
340     }
341    
342     byte [] maskKey = new byte[]{0,0,0,0};
343    
344     if (mask){
345     Array.Copy(buffer,2,maskKey,0,4);
346     }
347    
348     byte [] unmaskedData = new byte[payloadLen];
349    
350    
351     Array.Copy(buffer,6,unmaskedData,0,(int)payloadLen);
352    
353     for (int i =0;i<(int)payloadLen;++i){
354     unmaskedData[i]=(byte)(unmaskedData[i]^maskKey[i%4]);
355     }
356     return encodingUTF8.GetString(unmaskedData);
357     }
358     public void sendMessage(byte[] message){
359    
360     if (useHixie){
361     byte [] data = new byte[message.Length+2];
362     data[0] = 0;
363     data[message.Length+1] = 255;
364     Array.Copy((message),0,data,1,message.Length);
365     client.Send(data,data.Length,SocketFlags.None);
366     return;
367     }
368     //System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
369     byte [] unmaskedData = (message);
370     int len = unmaskedData.Length;
371     bool big = false;
372     bool bigger = false;
373    
374     if (len>256*256+256){
375     bigger = true;
376     }else if (len>125){
377     big = true;
378     }
379    
380     byte [] buffer;
381    
382     if (bigger){
383     buffer = new byte[len+6+(mask?4:0)];
384     Array.Clear(buffer,0,len+6+(mask?4:0));
385     }else if (big){
386     buffer = new byte[len+4+(mask?4:0)];
387     Array.Clear(buffer,0,len+4+(mask?4:0));
388     }else{
389     buffer = new byte[len+2+(mask?4:0)];
390     Array.Clear(buffer,0,len+2+(mask?4:0));
391     }
392     int optcode = 1;
393     buffer[0] = (byte)(128 + optcode);
394    
395     int maskVal = 0;
396    
397     if (mask){
398     maskVal = 128;
399     }
400    
401     if (bigger){
402     buffer[1] = (byte)(maskVal + 127);
403     buffer[5] = (byte)(len%256);
404     len/=256;
405     buffer[4] = (byte)(len%256);
406     len/=256;
407     buffer[3] = (byte)(len%256);
408     len/=256;
409     buffer[2] = (byte)(len%256);
410     }else if (big){
411     buffer[1] = (byte)(maskVal + 126);
412     buffer[2] = (byte)(len/256);
413     buffer[3] = (byte)(len%256);
414     }else{
415     buffer[1] = (byte)(maskVal + len );
416     }
417    
418     if (mask){
419     byte [] maskKey = new byte[4];
420     r.NextBytes(maskKey);
421     if (bigger){
422     Array.Copy(maskKey,0,buffer,6,4);
423     }else if (big){
424     Array.Copy(maskKey,0,buffer,4,4);
425     }else{
426     Array.Copy(maskKey,0,buffer,2,4);
427     }
428     if (bigger){
429     for (int i = 0 ; i<unmaskedData.Length;++i){
430     buffer[10+i] = (byte)(unmaskedData[i]^maskKey[i%4]);
431     }
432     }else if (big){
433     for (int i = 0 ; i<unmaskedData.Length;++i){
434     buffer[8+i] = (byte)(unmaskedData[i]^maskKey[i%4]);
435     }
436     }else{
437     for (int i = 0 ; i<unmaskedData.Length;++i){
438     buffer[6+i] = (byte)(unmaskedData[i]^maskKey[i%4]);
439     }
440     }
441     }else{
442     int offset = 0;
443     if (bigger){
444     offset=6;
445     }else if (big){
446     offset=4;
447     }else{
448     offset=2;
449     }
450     for (int i = 0 ; i<unmaskedData.Length;++i){
451     buffer[offset+i] = (byte)(unmaskedData[i]);
452     }
453     }
454    
455     client.Send(buffer);
456    
457    
458     }
459     public void sendMessage(string message){
460    
461     if (useHixie){
462     byte [] data = new byte[message.Length+2];
463     data[0] = 0;
464     data[message.Length+1] = 255;
465     Array.Copy(encodingUTF8.GetBytes(message),0,data,1,message.Length);
466     client.Send(data,data.Length,SocketFlags.None);
467     return;
468     }
469     //System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
470     byte [] unmaskedData = encoding.GetBytes(message);
471     int len = unmaskedData.Length;
472     bool big = false;
473     bool bigger = false;
474    
475     if (len>256*256+256){
476     bigger = true;
477     }else if (len>125){
478     big = true;
479     }
480    
481     byte [] buffer;
482    
483     if (bigger){
484     buffer = new byte[len+6+(mask?4:0)];
485     Array.Clear(buffer,0,len+6+(mask?4:0));
486     }else if (big){
487     buffer = new byte[len+4+(mask?4:0)];
488     Array.Clear(buffer,0,len+4+(mask?4:0));
489     }else{
490     buffer = new byte[len+2+(mask?4:0)];
491     Array.Clear(buffer,0,len+2+(mask?4:0));
492     }
493     int optcode = 1;
494     buffer[0] = (byte)(128 + optcode);
495    
496     int maskVal = 0;
497    
498     if (mask){
499     maskVal = 128;
500     }
501    
502     if (bigger){
503     buffer[1] = (byte)(maskVal + 127);
504     buffer[5] = (byte)(len%256);
505     len/=256;
506     buffer[4] = (byte)(len%256);
507     len/=256;
508     buffer[3] = (byte)(len%256);
509     len/=256;
510     buffer[2] = (byte)(len%256);
511     }else if (big){
512     buffer[1] = (byte)(maskVal + 126);
513     buffer[2] = (byte)(len/256);
514     buffer[3] = (byte)(len%256);
515     }else{
516     buffer[1] = (byte)(maskVal + len );
517     }
518    
519     if (mask){
520     byte [] maskKey = new byte[4];
521     r.NextBytes(maskKey);
522     if (bigger){
523     Array.Copy(maskKey,0,buffer,6,4);
524     }else if (big){
525     Array.Copy(maskKey,0,buffer,4,4);
526     }else{
527     Array.Copy(maskKey,0,buffer,2,4);
528     }
529     if (bigger){
530     for (int i = 0 ; i<unmaskedData.Length;++i){
531     buffer[10+i] = (byte)(unmaskedData[i]^maskKey[i%4]);
532     }
533     }else if (big){
534     for (int i = 0 ; i<unmaskedData.Length;++i){
535     buffer[8+i] = (byte)(unmaskedData[i]^maskKey[i%4]);
536     }
537     }else{
538     for (int i = 0 ; i<unmaskedData.Length;++i){
539     buffer[6+i] = (byte)(unmaskedData[i]^maskKey[i%4]);
540     }
541     }
542     }else{
543     int offset = 0;
544     if (bigger){
545     offset=6;
546     }else if (big){
547     offset=4;
548     }else{
549     offset=2;
550     }
551     for (int i = 0 ; i<unmaskedData.Length;++i){
552     buffer[offset+i] = (byte)(unmaskedData[i]);
553     }
554     }
555    
556     client.Send(buffer);
557    
558    
559     }
560     public string EncodeTo64(byte[] toEncode) {
561     byte[] toEncodeAsBytes = toEncode;
562     string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
563     return returnValue;
564     }
565     public string EncodeTo64(string toEncode) {
566     byte[] toEncodeAsBytes = encoding.GetBytes(toEncode);
567     string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
568     return returnValue;
569     }
570    
571     public Client(Socket client){
572     this.client = client;
573     client.BeginReceive(buffer, 0, 4096, 0, new AsyncCallback(onReceivedClientData),client);
574    
575    
576     }
577     public void close(){
578     this.client.Close();
579     }
580    
581     public void threadfunc (){
582    
583     }
584    
585    
586     public Thread createThread(){
587     thread = new Thread(new ThreadStart(this.threadfunc));
588     return thread;
589     }
590    
591     System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
592    
593     public void dumpBinary (BitArray b,int length){
594     Console.WriteLine("");
595     int counter = 0;
596     for (int i = 0;i<length;++i){
597     if (b[i]){
598     Console.Write(1);
599     }else{
600     Console.Write(0);
601     }
602     if (counter==0){
603     Console.Write(" ");
604     }
605     counter = (counter+1)%4;
606     }
607     Console.WriteLine("");
608     }
609    
610     public void dump (byte [] b,int size){
611     Console.WriteLine("{0} bytes received",size);
612     int offset = 0;
613    
614     while (offset<size){
615     Console.Write ("{0:X2} ",b[offset]);
616    
617     if (offset>0&&offset%16==0){
618    
619     Console.Write(encoding.GetString(b,offset-16,16));
620    
621     Console.WriteLine();
622     }
623     offset+=1;
624     }
625    
626     Console.WriteLine();
627    
628     }
629     }
630     }
631