Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- namespace Devart.Common
- {
- using System;
- using System.IO;
- using System.Net;
- using System.Net.Cache;
- using System.Runtime.InteropServices;
- using System.Text;
- using System.Threading;
- internal class HttpVio : VioWithProxy
- {
- private bool blocking;
- private ManualResetEvent connectEvt;
- private string connectionId;
- private string connectUrl;
- private const int defaultTimeout = 0x7530;
- private int instanceId;
- private bool keepAlive;
- private static int LastInstanceId;
- private HttpWebRequest lastReadRequest;
- private const int minimumTimeout = 0x1b58;
- private System.Threading.Timer notificationTimer;
- private string password;
- private int portID;
- private int prevByte;
- private Stream prevReadStream;
- private int scriptNotificationTime;
- private object sendingLock;
- private string testUrl;
- private Exception threadException;
- private string url;
- private bool UseProxy;
- private string user;
- public HttpVio(HttpOptions options, string targetHost, int targetPort) : this(options.Url, options.User, options.Password, targetHost, targetPort, options.KeepAlive)
- {
- }
- public HttpVio(string url, string user, string password, string targetHost, int targetPort, bool keepAlive)
- {
- this.keepAlive = true;
- this.blocking = true;
- this.instanceId = Interlocked.Increment(ref LastInstanceId);
- this.url = url;
- this.user = user;
- this.password = password;
- this.keepAlive = keepAlive;
- Random random = new Random(Environment.TickCount);
- this.connectionId = random.Next(0xf4240) + "_" + random.Next(0xf4240);
- this.connectUrl = string.Format(url + "?a=c&s={0}&p={1}&id={2}", targetHost, targetPort, this.connectionId);
- this.testUrl = string.Format(url + "?a=t&s={0}&p={1}&id={2}", targetHost, targetPort, this.connectionId);
- this.sendingLock = new object();
- }
- private void CheckConnectResponse(Stream responseStream)
- {
- StreamReader reader = new StreamReader(responseStream);
- try
- {
- bool flag = false;
- string s = reader.ReadLine();
- s.TrimStart(new char[0]);
- flag = int.TryParse(s, out this.portID);
- s = reader.ReadLine();
- if (!flag)
- {
- throw new ProxyException("HTTP Script invalid connect response.");
- }
- flag = int.TryParse(s, out this.scriptNotificationTime);
- int num = 0;
- if (this.Timeout > 0)
- {
- num = this.Timeout / 0x3e8;
- }
- if (num == 0)
- {
- num = 7;
- }
- this.scriptNotificationTime = (this.scriptNotificationTime > (2 * num)) ? (this.scriptNotificationTime - num) : (this.scriptNotificationTime / 2);
- this.scriptNotificationTime *= 0x3e8;
- }
- finally
- {
- reader.Close();
- }
- }
- private void CheckResponseSuccess(Stream stream, bool closeOnError)
- {
- if (stream == null)
- {
- throw new ArgumentNullException("stream");
- }
- try
- {
- int num = 0;
- StringBuilder builder = new StringBuilder(ScriptResponseFlags.FlagLength);
- while (num < ScriptResponseFlags.FlagLength)
- {
- int num2 = stream.ReadByte();
- if (num2 == -1)
- {
- throw new ProxyException("Invalid script response. Failed to read success flag.");
- }
- builder.Append((char) num2);
- num++;
- }
- string strA = builder.ToString();
- if (string.Compare(strA, "OK:", StringComparison.InvariantCultureIgnoreCase) != 0)
- {
- string str2;
- int num3;
- if (string.Compare(strA, "ER:", StringComparison.InvariantCultureIgnoreCase) == 0)
- {
- str2 = string.Empty;
- }
- else
- {
- str2 = "HTTP Script unknown error: " + strA;
- }
- builder.Length = 0;
- builder.Append(str2);
- while ((num3 = stream.ReadByte()) != -1)
- {
- builder.Append((char) num3);
- }
- if (builder.Length > 0)
- {
- throw new ProxyException(builder.ToString());
- }
- throw new ProxyException("HTTP Script reported error.");
- }
- }
- catch
- {
- try
- {
- if (closeOnError)
- {
- base.Close();
- }
- }
- catch
- {
- }
- throw;
- }
- }
- private void CheckThreadException()
- {
- if (this.threadException != null)
- {
- Exception threadException = this.threadException;
- this.threadException = null;
- throw threadException;
- }
- }
- protected override void CloseInternal()
- {
- try
- {
- HttpWebRequest request = null;
- try
- {
- request = this.CreateRequest(this.url, 'x', "GET");
- request.Timeout = 0x1b58;
- request.GetResponse();
- }
- catch
- {
- }
- finally
- {
- if (request != null)
- {
- CloseRequest(request);
- }
- }
- if (this.notificationTimer != null)
- {
- this.notificationTimer.Dispose();
- this.notificationTimer = null;
- }
- }
- catch
- {
- }
- }
- private static void CloseRequest(HttpWebRequest request)
- {
- CloseRequest(request, false);
- }
- private static void CloseRequest(HttpWebRequest request, bool isConnect)
- {
- request.Abort();
- if (isConnect)
- {
- request.ServicePoint.CloseConnectionGroup(request.ConnectionGroupName);
- }
- }
- private WebProxy CreateProxySettings()
- {
- WebProxy proxy = new WebProxy(base.ProxyOptions.Host, base.ProxyOptions.Port);
- proxy.Credentials = new NetworkCredential(base.ProxyOptions.User, base.ProxyOptions.Password);
- return proxy;
- }
- private HttpWebRequest CreateRequest(string url, char command, string method)
- {
- System.Net.ServicePointManager.Expect100Continue = false;
- string str;
- if ((command != 't') && (command != 'c'))
- {
- str = "?a=" + command;
- }
- else
- {
- str = string.Empty;
- }
- WebRequest request = WebRequest.Create(string.Concat(url, str, "&port=", this.portID, "&uuid=", Guid.NewGuid().ToString("N")));
- HttpWebRequest request2 = (HttpWebRequest) request;
- request2.ConnectionGroupName = this.GetConnectionGroupName(command);
- request2.KeepAlive = this.KeepAlive;
- request.Method = method;
- //request.ContentType = "application/x-www-form-urlencoded";
- if (this.Timeout != 0)
- {
- request.Timeout = this.Timeout;
- }
- if (!string.IsNullOrEmpty(this.user))
- {
- request.Credentials = new NetworkCredential(this.user, this.password);
- }
- if (this.UseProxy)
- {
- request.Proxy = this.CreateProxySettings();
- request2.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
- }
- return request2;
- }
- private Stream ExecuteGetRequest(string url, char command, out HttpWebRequest request)
- {
- return this.ExecuteGetRequest(url, command, true, out request);
- }
- private Stream ExecuteGetRequest(string url, char command, bool closeOnError, out HttpWebRequest request)
- {
- Stream responseStream = null;
- lock (this.sendingLock)
- {
- this.CheckThreadException();
- request = this.CreateRequest(url, command, "GET");
- responseStream = request.GetResponse().GetResponseStream();
- }
- this.CheckResponseSuccess(responseStream, closeOnError);
- return responseStream;
- }
- private string GetConnectionGroupName(char command)
- {
- return string.Concat(new object[] { "HttpVio_Transfer_", command, "_", this.instanceId.ToString() });
- }
- private int GetTimeout()
- {
- if (this.Timeout == 0)
- {
- return 0x7530;
- }
- return this.Timeout;
- }
- private void OnScriptNotification(object obj)
- {
- object obj2;
- if (this.notificationTimer != null)
- {
- this.notificationTimer.Dispose();
- this.notificationTimer = null;
- }
- Monitor.Enter(obj2 = this.sendingLock);
- try
- {
- HttpWebRequest request = this.CreateRequest(this.url, 'l', "GET");
- try
- {
- Stream responseStream = request.GetResponse().GetResponseStream();
- this.CheckResponseSuccess(responseStream, true);
- }
- finally
- {
- CloseRequest(request);
- }
- this.StartNotificationTimer();
- }
- catch (Exception exception)
- {
- this.threadException = exception;
- }
- finally
- {
- Monitor.Exit(obj2);
- }
- }
- private void StartHttpServerScript(object obj)
- {
- try
- {
- string connectUrl;
- if (this.blocking)
- {
- connectUrl = this.connectUrl;
- }
- else
- {
- connectUrl = this.connectUrl + "&nonblock";
- }
- HttpWebRequest request = this.CreateRequest(connectUrl, 'c', "GET");
- request.Timeout = this.GetTimeout();
- request.GetResponse();
- CloseRequest(request, true);
- this.connectEvt.Set();
- }
- catch
- {
- }
- }
- private void StartNotificationTimer()
- {
- if (this.notificationTimer != null)
- {
- this.notificationTimer.Change(this.scriptNotificationTime, this.scriptNotificationTime);
- }
- else
- {
- this.notificationTimer = new System.Threading.Timer(new TimerCallback(this.OnScriptNotification), null, this.scriptNotificationTime, this.scriptNotificationTime);
- }
- }
- protected override void TimeoutlessConnect(bool useProxy)
- {
- bool flag;
- this.UseProxy = useProxy;
- HttpWebRequest request = null;
- int num = 0;
- this.connectEvt = new ManualResetEvent(false);
- int millisecondsTimeout = 100;
- do
- {
- this.connectEvt.Reset();
- ThreadPool.QueueUserWorkItem(new WaitCallback(this.StartHttpServerScript));
- bool flag2 = false;
- flag = false;
- int timeout = this.GetTimeout();
- while ((!flag2 && !flag) && (millisecondsTimeout < timeout))
- {
- flag2 = this.connectEvt.WaitOne(millisecondsTimeout, false);
- try
- {
- Stream responseStream = this.ExecuteGetRequest(this.testUrl, 't', false, out request);
- this.CheckConnectResponse(responseStream);
- flag = true;
- }
- catch
- {
- flag = false;
- }
- finally
- {
- if (request != null)
- {
- CloseRequest(request);
- }
- }
- millisecondsTimeout *= 2;
- }
- num++;
- }
- while (!flag && (num < 3));
- if (!flag)
- {
- throw new InvalidOperationException("Can't establish HTTP connection.");
- }
- this.StartNotificationTimer();
- }
- protected override int UnbufferedRead(byte[] buffer, int offset, int count)
- {
- Stream prevReadStream;
- int num = 0;
- int num2 = 0;
- if (this.prevReadStream != null)
- {
- if (count == 0)
- {
- return 0;
- }
- buffer[offset] = (byte) this.prevByte;
- num2++;
- prevReadStream = this.prevReadStream;
- }
- else
- {
- int tickCount = Environment.TickCount;
- int timeout = this.Timeout;
- prevReadStream = this.ExecuteGetRequest(this.url, 'r', out this.lastReadRequest);
- this.StartNotificationTimer();
- }
- while ((num2 < count) && ((num = prevReadStream.ReadByte()) != -1))
- {
- buffer[offset + num2] = (byte) num;
- num2++;
- }
- if (num == -1)
- {
- this.prevReadStream = null;
- }
- else
- {
- this.prevByte = prevReadStream.ReadByte();
- if (this.prevByte != -1)
- {
- this.prevReadStream = prevReadStream;
- }
- else
- {
- this.prevReadStream = null;
- }
- }
- if ((this.prevReadStream == null) && (this.lastReadRequest != null))
- {
- CloseRequest(this.lastReadRequest);
- }
- return num2;
- }
- protected override void WriteInternal(byte[] buffer, int offset, int count)
- {
- // begin fix
- /*
- var postString = "base64body=" + Convert.ToBase64String(buffer, offset, count, Base64FormattingOptions.None);
- buffer = Encoding.ASCII.GetBytes(postString);
- offset = 0;
- count = buffer.Length;
- */
- // end fix
- lock (this.sendingLock)
- {
- this.CheckThreadException();
- HttpWebRequest request = this.CreateRequest(this.url, 'w', "POST");
- request.ContentLength = count;
- Stream requestStream = request.GetRequestStream();
- requestStream.Write(buffer, offset, count);
- requestStream.Close();
- Stream responseStream = request.GetResponse().GetResponseStream();
- this.CheckResponseSuccess(responseStream, true);
- CloseRequest(request);
- this.StartNotificationTimer();
- }
- }
- public bool Blocking
- {
- get
- {
- return this.blocking;
- }
- set
- {
- this.blocking = value;
- }
- }
- public bool KeepAlive
- {
- get
- {
- return this.keepAlive;
- }
- set
- {
- this.keepAlive = value;
- }
- }
- private static class ScriptCommands
- {
- public const char Close = 'x';
- public const char Connect = 'c';
- public const char Lease = 'l';
- public const char Read = 'r';
- public const char Test = 't';
- public const char Write = 'w';
- }
- private static class ScriptResponseFlags
- {
- public const string Error = "ER:";
- public static readonly int FlagLength = "OK:".Length;
- public const string Success = "OK:";
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement