You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

PACServer.cs 3.5 kB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. using shadowsocks_csharp.Properties;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.IO.Compression;
  6. using System.Net;
  7. using System.Net.Sockets;
  8. using System.Text;
  9. namespace shadowsocks_csharp.Controller
  10. {
  11. class PACServer
  12. {
  13. Socket listener;
  14. public void Start()
  15. {
  16. // Create a TCP/IP socket.
  17. listener = new Socket(AddressFamily.InterNetwork,
  18. SocketType.Stream, ProtocolType.Tcp);
  19. IPEndPoint localEndPoint = new IPEndPoint(0, 8090);
  20. // Bind the socket to the local endpoint and listen for incoming connections.
  21. listener.Bind(localEndPoint);
  22. listener.Listen(100);
  23. listener.BeginAccept(
  24. new AsyncCallback(AcceptCallback),
  25. listener);
  26. }
  27. public void AcceptCallback(IAsyncResult ar)
  28. {
  29. try
  30. {
  31. Socket listener = (Socket)ar.AsyncState;
  32. listener.BeginAccept(
  33. new AsyncCallback(AcceptCallback),
  34. listener);
  35. Socket conn = listener.EndAccept(ar);
  36. conn.BeginReceive(new byte[1024], 0, 256, 0,
  37. new AsyncCallback(receiveCallback), conn);
  38. }
  39. catch (Exception e)
  40. {
  41. Console.WriteLine(e.ToString());
  42. }
  43. }
  44. private string getPACContent()
  45. {
  46. // TODO try pac.txt in current directory
  47. byte[] pacGZ = Resources.proxy_pac_txt;
  48. byte[] buffer = new byte[1024 * 1024]; // builtin pac gzip size: maximum 1M
  49. int n;
  50. using (GZipStream input = new GZipStream(new MemoryStream(pacGZ),
  51. CompressionMode.Decompress, false))
  52. {
  53. n = input.Read(buffer, 0, buffer.Length);
  54. if (n == 0)
  55. {
  56. throw new IOException("can not decompress pac");
  57. }
  58. return System.Text.Encoding.UTF8.GetString(buffer, 0, n);
  59. }
  60. }
  61. private void receiveCallback(IAsyncResult ar)
  62. {
  63. Socket conn = (Socket)ar.AsyncState;
  64. try
  65. {
  66. int bytesRead = conn.EndReceive(ar);
  67. string pac = getPACContent();
  68. string proxy = "PROXY 127.0.0.1:8123; DIRECT;";
  69. pac = pac.Replace("__PROXY__", proxy);
  70. if (bytesRead > 0)
  71. {
  72. string text = String.Format(@"HTTP/1.1 200 OK
  73. Server: Shadowsocks
  74. Content-Type: application/x-ns-proxy-autoconfig
  75. Content-Length: {0}
  76. Connection: Close
  77. ", System.Text.Encoding.UTF8.GetBytes(pac).Length) + pac;
  78. byte[] response = System.Text.Encoding.UTF8.GetBytes(text);
  79. conn.BeginSend(response, 0, response.Length, 0, new AsyncCallback(sendCallback), conn);
  80. }
  81. else
  82. {
  83. conn.Close();
  84. }
  85. }
  86. catch (Exception e)
  87. {
  88. Console.WriteLine(e.ToString());
  89. conn.Close();
  90. }
  91. }
  92. private void sendCallback(IAsyncResult ar)
  93. {
  94. Socket conn = (Socket)ar.AsyncState;
  95. conn.Shutdown(SocketShutdown.Send);
  96. }
  97. }
  98. }