private async Task <string> QueryAsync(
            string obj, string server, bool clearHints, CancellationToken ct, object value = null)
        {
            var args = new YaWhoisClientEventArgs()
            {
                Value = value
            };

            try
            {
                lock (QueryParser)
                {
                    PrepareQuery(obj, server, clearHints);
                    args.Parser   = GetDataParser();
                    args.Server   = QueryParser.Server;
                    args.Query    = QueryParser.ServerQuery;
                    args.Encoding = QueryParser.ServerEncoding;
                }

                ct.ThrowIfCancellationRequested();

                int conn_timeout, rdwr_timeout;
                lock (__locker)
                {
                    OnRequestReady(args);
                    conn_timeout = ConnectTimeout;
                    rdwr_timeout = ReadWriteTimeout;
                }

                args.Response = await FetchAsync(args.Server, args.Query, args.Encoding, ct, conn_timeout, rdwr_timeout);

                OnResponseReceived(args);

                if (args.Parser != null)
                {
                    args.Referral = args.Parser.GetReferral(args.Response);
                }
                else
                {
                    args.Referral = null;
                }

                OnResponseParsed(args);

                if (!string.IsNullOrEmpty(args.Referral))
                {
                    return(await QueryAsync(obj, args.Referral, false, ct, value));
                }

                return(args.Response);
            }
            catch (Exception e)
            {
                args.Exception = e;
                OnExceptionThrown(args);
                return(null);
            }
        }
        private string Query(string obj, string server, bool clearHints, object value)
        {
            var args = new YaWhoisClientEventArgs()
            {
                Value = value
            };

            lock (QueryParser)
            {
                PrepareQuery(obj, server, clearHints);
                args.Parser   = GetDataParser();
                args.Server   = QueryParser.Server;
                args.Query    = QueryParser.ServerQuery;
                args.Encoding = QueryParser.ServerEncoding;
            }

            int conn_timeout, rdwr_timeout;

            lock (__locker)
            {
                OnRequestReady(args);
                conn_timeout = ConnectTimeout;
                rdwr_timeout = ReadWriteTimeout;
            }

            args.Response = Fetch(args.Server, args.Query, args.Encoding, conn_timeout, rdwr_timeout);

            OnResponseReceived(args);

            if (args.Parser != null)
            {
                args.Referral = args.Parser.GetReferral(args.Response);
            }
            else
            {
                args.Referral = null;
            }

            OnResponseParsed(args);

            if (!string.IsNullOrEmpty(args.Referral))
            {
                return(Query(obj, args.Referral, false, value));
            }

            return(args.Response);
        }
 protected virtual void OnExceptionThrown(YaWhoisClientEventArgs e)
 {
     ExceptionThrown?.Invoke(this, e);
     WhenExceptionThrown?.Invoke(this, e);
 }
 protected virtual void OnResponseParsed(YaWhoisClientEventArgs e)
 {
     ResponseParsed?.Invoke(this, e);
     WhenResponseParsed?.Invoke(this, e);
 }
 protected virtual void OnResponseReceived(YaWhoisClientEventArgs e)
 {
     BeforeParseResponse?.Invoke(this, e);
     WhenResponseReceived?.Invoke(this, e);
 }
 protected virtual void OnRequestReady(YaWhoisClientEventArgs e)
 {
     BeforeSendRequest?.Invoke(this, e);
     WhenRequestReady?.Invoke(this, e);
 }