/// <summary>
        /// Executes an API call and returns the result
        ///
        /// <para>If using the ClientID or OAuth provided to the constructor, enforces the rate-limit</para>
        /// </summary>
        /// <param name="type">The HTTP method to use</param>
        /// <param name="url">The URL to query</param>
        /// <param name="post">If set, post data to send</param>
        /// <param name="isJson">If true, the post data is JSON</param>
        /// <param name="oauth">If set, overrides the OAuth token to use for the request</param>
        /// <returns>The result from Twitch</returns>
        /// <exception cref="Exceptions.AuthorizationRequiredException">Thrown if both <see cref="TwitchAPIHelix.clientidOrOauth"/> and
        /// <paramref name="oauth"/> are not set</exception>
        /// <exception cref="Exceptions.TwitchErrorException">Thrown if Twitch returns an error</exception>
        /// <exception cref="System.Net.WebException">Thrown if the HTTP request fails</exception>
        private string GetData(Request_type type, string url, string post, bool isJson, string oauth)
        {
            if (oauth != null && oauth.Length > 0)
            {
                goto ExecuteRequest;
            }

            goto CheckLimit;
WaitForLimit:
            if (this.ratelimit_reset.CompareTo(DateTime.UtcNow) > 0)
            {
                Thread.Sleep(this.ratelimit_reset - DateTime.UtcNow);
            }

            lock (TwitchAPIHelix.getDataLock)
            {
                if (this.ratelimit_remaining == 0)
                {
                    this.ratelimit_remaining = this.ratelimit_limit;
                    this.ratelimit_reset     = DateTime.UtcNow.AddSeconds(60);
                }
            }

            Thread.Sleep(300);

CheckLimit:
            lock (TwitchAPIHelix.getDataLock)
            {
                if (this.ratelimit_remaining > 0)
                {
                    this.ratelimit_remaining--;
                    goto ExecuteRequest;
                }
                else
                {
                    goto WaitForLimit;
                }
            }

ExecuteRequest:
            string ret = "";

            if (this.clientidOrOauth.Length == 0 && (oauth == null || oauth.Length == 0))
            {
                throw new Exceptions.AuthorizationRequiredException();
            }

            try
            {
                url += url.Contains("?") ? "&" : "?";

                url += "tick=" + (int)Math.Floor(DateTimeOffset.UtcNow.ToUnixTimeSeconds() / 30.0);

                Uri            uri = new Uri(url);
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri);

                req.ContentType = isJson ? "application/json" : "application/x-www-form-urlencoded";

                if (oauth != null && oauth.Length > 0)
                {
                    req.Headers.Add("Authorization", "Bearer " + oauth.Replace("oauth:", ""));
                }
                else if (this.isOauth)
                {
                    req.Headers.Add("Authorization", "Bearer " + this.clientidOrOauth);
                }
                else
                {
                    req.Headers.Add("Client-ID", this.clientidOrOauth);
                }

                req.Method      = type.ToString();
                req.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.CacheIfAvailable);
                req.Timeout     = timeout;
                req.UserAgent   = user_agent;
                req.KeepAlive   = true;

                if (isJson && post.Length == 0)
                {
                    post = "{}";
                }

                if (post.Length > 0)
                {
                    Stream requestStream = req.GetRequestStream();
                    requestStream.ReadTimeout  = timeout;
                    requestStream.WriteTimeout = timeout;

                    using (StreamWriter reqStream = new StreamWriter(requestStream))
                    {
                        reqStream.Write(post);
                    }
                }

                using (HttpWebResponse res = (HttpWebResponse)req.GetResponse())
                {
                    Stream responseStream = res.GetResponseStream();
                    responseStream.ReadTimeout  = timeout;
                    responseStream.WriteTimeout = timeout;

                    if (oauth == null || oauth.Length == 0)
                    {
                        int.TryParse(res.Headers.Get("Ratelimit-Limit"), out this.ratelimit_limit);
                        int.TryParse(res.Headers.Get("Ratelimit-Remaining"), out this.ratelimit_remaining);
                        long.TryParse(res.Headers.Get("Ratelimit-Reset"), out long ts);

                        this.ratelimit_limit = Math.Max(this.ratelimit_limit, 30);
                        this.ratelimit_reset = epoch.AddSeconds(ts);
                    }

                    using (StreamReader resStream = new StreamReader(responseStream))
                    {
                        ret = resStream.ReadToEnd();
                    }

                    if ((int)res.StatusCode < 200 || (int)res.StatusCode > 299)
                    {
                        DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(TwitchError));

                        MemoryStream ms = null;
                        TwitchError  te;

                        try
                        {
                            ms = new MemoryStream(Encoding.UTF8.GetBytes(ret))
                            {
                                Position = 0
                            };
                            te = (TwitchError)js.ReadObject(ms);
                        }
                        finally
                        {
                            if (ms != null)
                            {
                                ms.Dispose();
                            }
                        }

                        throw new Exceptions.TwitchErrorException(te.status + ": " + te.message);
                    }
                }
            }
            catch (System.Exception e)
            {
                if (e.GetType() == typeof(WebException))
                {
                    if (((WebException)e).Status == WebExceptionStatus.ProtocolError)
                    {
                        using (HttpWebResponse res = (HttpWebResponse)((WebException)e).Response)
                        {
                            Stream responseStream = res.GetResponseStream();
                            responseStream.ReadTimeout  = timeout;
                            responseStream.WriteTimeout = timeout;

                            using (StreamReader resStream = new StreamReader(responseStream))
                            {
                                ret = resStream.ReadToEnd();
                            }

                            if ((int)res.StatusCode < 200 || (int)res.StatusCode > 299)
                            {
                                DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(TwitchError));

                                MemoryStream ms = null;
                                TwitchError  te;

                                try
                                {
                                    ms = new MemoryStream(Encoding.UTF8.GetBytes(ret))
                                    {
                                        Position = 0
                                    };
                                    te = (TwitchError)js.ReadObject(ms);
                                }
                                finally
                                {
                                    if (ms != null)
                                    {
                                        ms.Dispose();
                                    }
                                }

                                throw new Exceptions.TwitchErrorException(te.status + ": " + te.message);
                            }
                        }
                    }
                    else
                    {
                        throw;
                    }
                }
                else
                {
                    throw;
                }
            }

            return(ret);
        }
        public static async Task <string> GetResponse(string strSubAddress, Dictionary <string, string> pairs, Request_type type = Request_type.TYPE_GET)
        {
            if (!ICUtility.Ping(strServer))
            {
                return("");
            }

            string url = "http://" + strServer + "/" + strSubAddress;

            return(await HttpServer.GetHttpResponse(url, pairs, 4000, type));
        }
        public static async Task <string> GetResponse(string strSubAddress, Dictionary <string, string> pairs, Request_type type = Request_type.TYPE_GET)
        {
            //if (!ICUtility.Ping(strServer)) return "";
            string url = "";

            if (strServer.Contains("http"))
            {
                url = strServer + "/" + strSubAddress;
            }
            else
            {
                url = "http://" + strServer + "/" + strSubAddress;
            }

            return(await HttpServer.GetHttpResponse(url, pairs, 4000, type));
        }
        public static async Task <string> GetHttpResponse(string url, Dictionary <string, string> paraData, int Timeout, Request_type type = Request_type.TYPE_GET)
        {
            HttpWebRequest  request  = null;
            HttpWebResponse response = null;
            string          temp     = string.Empty;
            string          ret;

            try
            {
                string strContentType = "application/x-www-form-urlencoded";
                if (Request_type.TYPE_POST == type)
                {
                    if (paraData != null)
                    {
                        foreach (var item in paraData)
                        {
                            if (item.Key == "jsonKey")  //待优化
                            {
                                temp          += item.Value + "&";
                                strContentType = "application/json;charset=UTF-8";
                            }
                            else
                            {
                                temp += item.Key + "=" + item.Value + "&";
                            }
                        }
                        temp = temp.Substring(0, temp.Length - 1);
                    }
                    Encoding       encoding  = Encoding.GetEncoding("utf-8");
                    byte[]         byteArray = encoding.GetBytes(temp);
                    HttpWebRequest webReq    = (HttpWebRequest)WebRequest.Create(new Uri(url));
                    webReq.Method        = "POST";
                    webReq.ContentType   = strContentType;
                    webReq.ContentLength = byteArray.Length;

                    Stream newStream = webReq.GetRequestStream();
                    newStream.Write(byteArray, 0, byteArray.Length);

                    HttpWebResponse response2 = null;

                    try
                    {
                        response2 = (HttpWebResponse)webReq.GetResponse();
                    }
                    catch (WebException ex)
                    {
                        response2 = (HttpWebResponse)ex.Response;
                    }


                    StreamReader sr = new StreamReader(response2.GetResponseStream(), encoding);

                    //  ret = sr.ReadToEnd();

                    ret = await sr.ReadToEndAsync();

                    sr.Close();
                    response2.Close();
                    newStream.Close();
                    return(ret);
                }
                else
                {
                    if (paraData != null)
                    {
                        foreach (var item in paraData)
                        {
                            temp += item.Key + "=" + item.Value + "&";
                        }
                        temp = temp.Substring(0, temp.Length - 1);
                    }


                    url            = url + "?" + temp;
                    request        = (HttpWebRequest)WebRequest.Create(url);
                    request.Method = "GET";

                    request.ContentType = "text/html;charset=UTF-8";
                    request.UserAgent   = null;
                    request.Timeout     = Timeout;

                    try
                    {
                        response = (HttpWebResponse)request.GetResponse();
                    }
                    catch (WebException ex)
                    {
                        response = (HttpWebResponse)ex.Response;
                    }
                    Stream       myResponseStream = response.GetResponseStream();
                    StreamReader myStreamReader   = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
                    // string retString = myStreamReader.ReadToEnd();

                    string retString = await myStreamReader.ReadToEndAsync();

                    myStreamReader.Close();
                    myResponseStream.Close();

                    return(retString);
                }
            }
            catch (Exception ee)
            {
                Logger.Error("服务器连接异常" + ee.StackTrace);
                return(string.Empty);
            }
            finally
            {
                if (response != null)
                {
                    response.Close();
                }
            }
        }