Advertisement
Guest User

Untitled

a guest
Jun 9th, 2017
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 17.43 KB | None | 0 0
  1. namespace Devart.Common
  2. {
  3.     using System;
  4.     using System.IO;
  5.     using System.Net;
  6.     using System.Net.Cache;
  7.     using System.Runtime.InteropServices;
  8.     using System.Text;
  9.     using System.Threading;
  10.  
  11.     internal class HttpVio : VioWithProxy
  12.     {
  13.         private bool blocking;
  14.         private ManualResetEvent connectEvt;
  15.         private string connectionId;
  16.         private string connectUrl;
  17.         private const int defaultTimeout = 0x7530;
  18.         private int instanceId;
  19.         private bool keepAlive;
  20.         private static int LastInstanceId;
  21.         private HttpWebRequest lastReadRequest;
  22.         private const int minimumTimeout = 0x1b58;
  23.         private System.Threading.Timer notificationTimer;
  24.         private string password;
  25.         private int portID;
  26.         private int prevByte;
  27.         private Stream prevReadStream;
  28.         private int scriptNotificationTime;
  29.         private object sendingLock;
  30.         private string testUrl;
  31.         private Exception threadException;
  32.         private string url;
  33.         private bool UseProxy;
  34.         private string user;
  35.  
  36.         public HttpVio(HttpOptions options, string targetHost, int targetPort) : this(options.Url, options.User, options.Password, targetHost, targetPort, options.KeepAlive)
  37.         {
  38.         }
  39.  
  40.         public HttpVio(string url, string user, string password, string targetHost, int targetPort, bool keepAlive)
  41.         {
  42.             this.keepAlive = true;
  43.             this.blocking = true;
  44.             this.instanceId = Interlocked.Increment(ref LastInstanceId);
  45.             this.url = url;
  46.             this.user = user;
  47.             this.password = password;
  48.             this.keepAlive = keepAlive;
  49.             Random random = new Random(Environment.TickCount);
  50.             this.connectionId = random.Next(0xf4240) + "_" + random.Next(0xf4240);
  51.             this.connectUrl = string.Format(url + "?a=c&s={0}&p={1}&id={2}", targetHost, targetPort, this.connectionId);
  52.             this.testUrl = string.Format(url + "?a=t&s={0}&p={1}&id={2}", targetHost, targetPort, this.connectionId);
  53.             this.sendingLock = new object();
  54.         }
  55.  
  56.         private void CheckConnectResponse(Stream responseStream)
  57.         {
  58.             StreamReader reader = new StreamReader(responseStream);
  59.             try
  60.             {
  61.                 bool flag = false;
  62.                 string s = reader.ReadLine();
  63.                 s.TrimStart(new char[0]);
  64.                 flag = int.TryParse(s, out this.portID);
  65.                 s = reader.ReadLine();
  66.                 if (!flag)
  67.                 {
  68.                     throw new ProxyException("HTTP Script invalid connect response.");
  69.                 }
  70.                 flag = int.TryParse(s, out this.scriptNotificationTime);
  71.                 int num = 0;
  72.                 if (this.Timeout > 0)
  73.                 {
  74.                     num = this.Timeout / 0x3e8;
  75.                 }
  76.                 if (num == 0)
  77.                 {
  78.                     num = 7;
  79.                 }
  80.                 this.scriptNotificationTime = (this.scriptNotificationTime > (2 * num)) ? (this.scriptNotificationTime - num) : (this.scriptNotificationTime / 2);
  81.                 this.scriptNotificationTime *= 0x3e8;
  82.             }
  83.             finally
  84.             {
  85.                 reader.Close();
  86.             }
  87.         }
  88.  
  89.         private void CheckResponseSuccess(Stream stream, bool closeOnError)
  90.         {
  91.             if (stream == null)
  92.             {
  93.                 throw new ArgumentNullException("stream");
  94.             }
  95.             try
  96.             {
  97.                 int num = 0;
  98.                 StringBuilder builder = new StringBuilder(ScriptResponseFlags.FlagLength);
  99.                 while (num < ScriptResponseFlags.FlagLength)
  100.                 {
  101.                     int num2 = stream.ReadByte();
  102.                     if (num2 == -1)
  103.                     {
  104.                         throw new ProxyException("Invalid script response. Failed to read success flag.");
  105.                     }
  106.                     builder.Append((char) num2);
  107.                     num++;
  108.                 }
  109.                 string strA = builder.ToString();
  110.                 if (string.Compare(strA, "OK:", StringComparison.InvariantCultureIgnoreCase) != 0)
  111.                 {
  112.                     string str2;
  113.                     int num3;
  114.                     if (string.Compare(strA, "ER:", StringComparison.InvariantCultureIgnoreCase) == 0)
  115.                     {
  116.                         str2 = string.Empty;
  117.                     }
  118.                     else
  119.                     {
  120.                         str2 = "HTTP Script unknown error: " + strA;
  121.                     }
  122.                     builder.Length = 0;
  123.                     builder.Append(str2);
  124.                     while ((num3 = stream.ReadByte()) != -1)
  125.                     {
  126.                         builder.Append((char) num3);
  127.                     }
  128.                     if (builder.Length > 0)
  129.                     {
  130.                         throw new ProxyException(builder.ToString());
  131.                     }
  132.                     throw new ProxyException("HTTP Script reported error.");
  133.                 }
  134.             }
  135.             catch
  136.             {
  137.                 try
  138.                 {
  139.                     if (closeOnError)
  140.                     {
  141.                         base.Close();
  142.                     }
  143.                 }
  144.                 catch
  145.                 {
  146.                 }
  147.                 throw;
  148.             }
  149.         }
  150.  
  151.         private void CheckThreadException()
  152.         {
  153.             if (this.threadException != null)
  154.             {
  155.                 Exception threadException = this.threadException;
  156.                 this.threadException = null;
  157.                 throw threadException;
  158.             }
  159.         }
  160.  
  161.         protected override void CloseInternal()
  162.         {
  163.             try
  164.             {
  165.                 HttpWebRequest request = null;
  166.                 try
  167.                 {
  168.                     request = this.CreateRequest(this.url, 'x', "GET");
  169.                     request.Timeout = 0x1b58;
  170.                     request.GetResponse();
  171.                 }
  172.                 catch
  173.                 {
  174.                 }
  175.                 finally
  176.                 {
  177.                     if (request != null)
  178.                     {
  179.                         CloseRequest(request);
  180.                     }
  181.                 }
  182.                 if (this.notificationTimer != null)
  183.                 {
  184.                     this.notificationTimer.Dispose();
  185.                     this.notificationTimer = null;
  186.                 }
  187.             }
  188.             catch
  189.             {
  190.             }
  191.         }
  192.  
  193.         private static void CloseRequest(HttpWebRequest request)
  194.         {
  195.             CloseRequest(request, false);
  196.         }
  197.  
  198.         private static void CloseRequest(HttpWebRequest request, bool isConnect)
  199.         {
  200.             request.Abort();
  201.             if (isConnect)
  202.             {
  203.                 request.ServicePoint.CloseConnectionGroup(request.ConnectionGroupName);
  204.             }
  205.         }
  206.  
  207.         private WebProxy CreateProxySettings()
  208.         {
  209.             WebProxy proxy = new WebProxy(base.ProxyOptions.Host, base.ProxyOptions.Port);
  210.             proxy.Credentials = new NetworkCredential(base.ProxyOptions.User, base.ProxyOptions.Password);
  211.             return proxy;
  212.         }
  213.  
  214.         private HttpWebRequest CreateRequest(string url, char command, string method)
  215.         {
  216.             //System.Net.ServicePointManager.Expect100Continue = false;
  217.  
  218.             string str;
  219.             if ((command != 't') && (command != 'c'))
  220.             {
  221.                 str = "?a=" + command;
  222.             }
  223.             else
  224.             {
  225.                 str = string.Empty;
  226.             }
  227.             WebRequest request = WebRequest.Create(string.Concat(url, str, "&port=", this.portID, "&uuid=", Guid.NewGuid().ToString("N")));
  228.             HttpWebRequest request2 = (HttpWebRequest) request;
  229.             request2.ConnectionGroupName = this.GetConnectionGroupName(command);
  230.             request2.KeepAlive = this.KeepAlive;
  231.             request.Method = method;
  232.             //request.ContentType = "application/x-www-form-urlencoded";
  233.             if (this.Timeout != 0)
  234.             {
  235.                 request.Timeout = this.Timeout;
  236.             }
  237.             if (!string.IsNullOrEmpty(this.user))
  238.             {
  239.                 request.Credentials = new NetworkCredential(this.user, this.password);
  240.             }
  241.             if (this.UseProxy)
  242.             {
  243.                 request.Proxy = this.CreateProxySettings();
  244.                 request2.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
  245.             }
  246.             return request2;
  247.         }
  248.  
  249.         private Stream ExecuteGetRequest(string url, char command, out HttpWebRequest request)
  250.         {
  251.             return this.ExecuteGetRequest(url, command, true, out request);
  252.         }
  253.  
  254.         private Stream ExecuteGetRequest(string url, char command, bool closeOnError, out HttpWebRequest request)
  255.         {
  256.             Stream responseStream = null;
  257.             lock (this.sendingLock)
  258.             {
  259.                 this.CheckThreadException();
  260.                 request = this.CreateRequest(url, command, "GET");
  261.                 responseStream = request.GetResponse().GetResponseStream();
  262.             }
  263.             this.CheckResponseSuccess(responseStream, closeOnError);
  264.             return responseStream;
  265.         }
  266.  
  267.         private string GetConnectionGroupName(char command)
  268.         {
  269.             return string.Concat(new object[] { "HttpVio_Transfer_", command, "_", this.instanceId.ToString() });
  270.         }
  271.  
  272.         private int GetTimeout()
  273.         {
  274.             if (this.Timeout == 0)
  275.             {
  276.                 return 0x7530;
  277.             }
  278.             return this.Timeout;
  279.         }
  280.  
  281.         private void OnScriptNotification(object obj)
  282.         {
  283.             object obj2;
  284.             if (this.notificationTimer != null)
  285.             {
  286.                 this.notificationTimer.Dispose();
  287.                 this.notificationTimer = null;
  288.             }
  289.             Monitor.Enter(obj2 = this.sendingLock);
  290.             try
  291.             {
  292.                 HttpWebRequest request = this.CreateRequest(this.url, 'l', "GET");
  293.                 try
  294.                 {
  295.                     Stream responseStream = request.GetResponse().GetResponseStream();
  296.                     this.CheckResponseSuccess(responseStream, true);
  297.                 }
  298.                 finally
  299.                 {
  300.                     CloseRequest(request);
  301.                 }
  302.                 this.StartNotificationTimer();
  303.             }
  304.             catch (Exception exception)
  305.             {
  306.                 this.threadException = exception;
  307.             }
  308.             finally
  309.             {
  310.                 Monitor.Exit(obj2);
  311.             }
  312.         }
  313.  
  314.         private void StartHttpServerScript(object obj)
  315.         {
  316.             try
  317.             {
  318.                 string connectUrl;
  319.                 if (this.blocking)
  320.                 {
  321.                     connectUrl = this.connectUrl;
  322.                 }
  323.                 else
  324.                 {
  325.                     connectUrl = this.connectUrl + "&nonblock";
  326.                 }
  327.                 HttpWebRequest request = this.CreateRequest(connectUrl, 'c', "GET");
  328.                 request.Timeout = this.GetTimeout();
  329.                 request.GetResponse();
  330.                 CloseRequest(request, true);
  331.                 this.connectEvt.Set();
  332.             }
  333.             catch
  334.             {
  335.             }
  336.         }
  337.  
  338.         private void StartNotificationTimer()
  339.         {
  340.             if (this.notificationTimer != null)
  341.             {
  342.                 this.notificationTimer.Change(this.scriptNotificationTime, this.scriptNotificationTime);
  343.             }
  344.             else
  345.             {
  346.                 this.notificationTimer = new System.Threading.Timer(new TimerCallback(this.OnScriptNotification), null, this.scriptNotificationTime, this.scriptNotificationTime);
  347.             }
  348.         }
  349.  
  350.         protected override void TimeoutlessConnect(bool useProxy)
  351.         {
  352.             bool flag;
  353.             this.UseProxy = useProxy;
  354.             HttpWebRequest request = null;
  355.             int num = 0;
  356.             this.connectEvt = new ManualResetEvent(false);
  357.             int millisecondsTimeout = 100;
  358.             do
  359.             {
  360.                 this.connectEvt.Reset();
  361.                 ThreadPool.QueueUserWorkItem(new WaitCallback(this.StartHttpServerScript));
  362.                 bool flag2 = false;
  363.                 flag = false;
  364.                 int timeout = this.GetTimeout();
  365.                 while ((!flag2 && !flag) && (millisecondsTimeout < timeout))
  366.                 {
  367.                     flag2 = this.connectEvt.WaitOne(millisecondsTimeout, false);
  368.                     try
  369.                     {
  370.                         Stream responseStream = this.ExecuteGetRequest(this.testUrl, 't', false, out request);
  371.                         this.CheckConnectResponse(responseStream);
  372.                         flag = true;
  373.                     }
  374.                     catch
  375.                     {
  376.                         flag = false;
  377.                     }
  378.                     finally
  379.                     {
  380.                         if (request != null)
  381.                         {
  382.                             CloseRequest(request);
  383.                         }
  384.                     }
  385.                     millisecondsTimeout *= 2;
  386.                 }
  387.                 num++;
  388.             }
  389.             while (!flag && (num < 3));
  390.             if (!flag)
  391.             {
  392.                 throw new InvalidOperationException("Can't establish HTTP connection.");
  393.             }
  394.             this.StartNotificationTimer();
  395.         }
  396.  
  397.         protected override int UnbufferedRead(byte[] buffer, int offset, int count)
  398.         {
  399.             Stream prevReadStream;
  400.             int num = 0;
  401.             int num2 = 0;
  402.             if (this.prevReadStream != null)
  403.             {
  404.                 if (count == 0)
  405.                 {
  406.                     return 0;
  407.                 }
  408.                 buffer[offset] = (byte) this.prevByte;
  409.                 num2++;
  410.                 prevReadStream = this.prevReadStream;
  411.             }
  412.             else
  413.             {
  414.                 int tickCount = Environment.TickCount;
  415.                 int timeout = this.Timeout;
  416.                 prevReadStream = this.ExecuteGetRequest(this.url, 'r', out this.lastReadRequest);
  417.                 this.StartNotificationTimer();
  418.             }
  419.             while ((num2 < count) && ((num = prevReadStream.ReadByte()) != -1))
  420.             {
  421.                 buffer[offset + num2] = (byte) num;
  422.                 num2++;
  423.             }
  424.             if (num == -1)
  425.             {
  426.                 this.prevReadStream = null;
  427.             }
  428.             else
  429.             {
  430.                 this.prevByte = prevReadStream.ReadByte();
  431.                 if (this.prevByte != -1)
  432.                 {
  433.                     this.prevReadStream = prevReadStream;
  434.                 }
  435.                 else
  436.                 {
  437.                     this.prevReadStream = null;
  438.                 }
  439.             }
  440.             if ((this.prevReadStream == null) && (this.lastReadRequest != null))
  441.             {
  442.                 CloseRequest(this.lastReadRequest);
  443.             }
  444.             return num2;
  445.         }
  446.  
  447.         protected override void WriteInternal(byte[] buffer, int offset, int count)
  448.         {
  449.             // begin fix
  450.             /*
  451.             var postString = "base64body=" + Convert.ToBase64String(buffer, offset, count, Base64FormattingOptions.None);
  452.             buffer = Encoding.ASCII.GetBytes(postString);
  453.             offset = 0;
  454.             count = buffer.Length;
  455.             */
  456.             // end fix
  457.             lock (this.sendingLock)
  458.             {
  459.                 this.CheckThreadException();
  460.                 HttpWebRequest request = this.CreateRequest(this.url, 'w', "POST");
  461.                 request.ServicePoint.Expect100Continue = false;
  462.                 request.ContentLength = count;
  463.                 Stream requestStream = request.GetRequestStream();
  464.                 requestStream.Write(buffer, offset, count);
  465.                 requestStream.Close();
  466.                 Stream responseStream = request.GetResponse().GetResponseStream();
  467.                 this.CheckResponseSuccess(responseStream, true);
  468.                 CloseRequest(request);
  469.                 this.StartNotificationTimer();
  470.             }
  471.         }
  472.  
  473.         public bool Blocking
  474.         {
  475.             get
  476.             {
  477.                 return this.blocking;
  478.             }
  479.             set
  480.             {
  481.                 this.blocking = value;
  482.             }
  483.         }
  484.  
  485.         public bool KeepAlive
  486.         {
  487.             get
  488.             {
  489.                 return this.keepAlive;
  490.             }
  491.             set
  492.             {
  493.                 this.keepAlive = value;
  494.             }
  495.         }
  496.  
  497.         private static class ScriptCommands
  498.         {
  499.             public const char Close = 'x';
  500.             public const char Connect = 'c';
  501.             public const char Lease = 'l';
  502.             public const char Read = 'r';
  503.             public const char Test = 't';
  504.             public const char Write = 'w';
  505.         }
  506.  
  507.         private static class ScriptResponseFlags
  508.         {
  509.             public const string Error = "ER:";
  510.             public static readonly int FlagLength = "OK:".Length;
  511.             public const string Success = "OK:";
  512.         }
  513.     }
  514. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement