예제 #1
0
        /// <summary>
        /// Sends an HTTP request and checks for errors
        /// </summary>
        /// <param name="method">HTTP method to use</param>
        /// <param name="endpoint">API endpoint (fx. /users/@me)</param>
        /// <param name="payload">JSON content</param>
        private Response Send(Leaf.xNet.HttpMethod method, string endpoint, object payload = null)
        {
            string json = "{}";

            if (payload != null)
            {
                if (payload.GetType() == typeof(string))
                {
                    json = (string)payload;
                }
                else
                {
                    json = JsonConvert.SerializeObject(payload);
                }
            }

            bool isEndpoint = !endpoint.StartsWith("http");

            if (isEndpoint)
            {
                endpoint = _discordClient.Config.ApiBaseUrl + endpoint;
            }

            bool hasData = method == Leaf.xNet.HttpMethod.POST || method == Leaf.xNet.HttpMethod.PATCH || method == Leaf.xNet.HttpMethod.PUT || method == Leaf.xNet.HttpMethod.DELETE;

            while (true)
            {
                try
                {
                    string resp;
                    int    statusCode;

                    if (_discordClient.Config.Proxy == null || _discordClient.Config.Proxy.Type == ProxyType.HTTP)
                    {
                        HttpClient client = new HttpClient(new HttpClientHandler()
                        {
                            Proxy = _discordClient.Config.Proxy == null ? null : new WebProxy(_discordClient.Config.Proxy.Host, _discordClient.Config.Proxy.Port)
                        });
                        if (_discordClient.Token != null)
                        {
                            client.DefaultRequestHeaders.Add("Authorization", _discordClient.Token);
                        }
                        if (Fingerprint != null)
                        {
                            client.DefaultRequestHeaders.Add("X-Fingerprint", Fingerprint);
                        }

                        client.DefaultRequestHeaders.Add("X-Super-Properties", _discordClient.Config.SuperProperties.Base64);

                        var response = client.SendAsync(new HttpRequestMessage()
                        {
                            Content = hasData ? new System.Net.Http.StringContent(json, Encoding.UTF8, "application/json") : null, Method = new System.Net.Http.HttpMethod(method.ToString()), RequestUri = new Uri(endpoint)
                        }).Result;

                        resp       = response.Content.ReadAsStringAsync().Result;
                        statusCode = (int)response.StatusCode;
                    }
                    else
                    {
                        HttpRequest msg = new HttpRequest
                        {
                            IgnoreProtocolErrors = true,
                            UserAgent            = _discordClient.Config.UserAgent,
                            Authorization        = _discordClient.Token
                        };
                        if (hasData)
                        {
                            msg.AddHeader(HttpHeader.ContentType, "application/json");
                        }
                        if (Fingerprint != null)
                        {
                            msg.AddHeader("X-Fingerprint", Fingerprint);
                        }

                        msg.AddHeader("X-Super-Properties", _discordClient.Config.SuperProperties.Base64);
                        if (_discordClient.Config.Proxy != null)
                        {
                            msg.Proxy = _discordClient.Config.Proxy;
                        }

                        var response = msg.Raw(method, endpoint, hasData ? new Leaf.xNet.StringContent(json) : null);
                        resp       = response.ToString();
                        statusCode = (int)response.StatusCode;
                    }

                    CheckResponse(resp, statusCode);
                    return(new Response(resp));
                }
                catch (RateLimitException ex)
                {
                    if (_discordClient.Config.RetryOnRateLimit)
                    {
                        Thread.Sleep(ex.RetryAfter);
                    }
                    else
                    {
                        throw;
                    }
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Sends an HTTP request and checks for errors
        /// </summary>
        /// <param name="method">HTTP method to use</param>
        /// <param name="endpoint">API endpoint (fx. /users/@me)</param>
        /// <param name="payload">JSON content</param>
        private async Task <DiscordHttpResponse> SendAsync(Leaf.xNet.HttpMethod method, string endpoint, object payload = null)
        {
            if (!endpoint.StartsWith("https"))
            {
                endpoint = DiscordHttpUtil.BuildBaseUrl(_discordClient.Config.ApiVersion, _discordClient.Config.SuperProperties.ReleaseChannel) + endpoint;
            }

            string json = "{}";

            if (payload != null)
            {
                if (payload.GetType() == typeof(string))
                {
                    json = (string)payload;
                }
                else
                {
                    json = JsonConvert.SerializeObject(payload);
                }
            }

            uint retriesLeft = _discordClient.Config.RestConnectionRetries;
            bool hasData     = method == Leaf.xNet.HttpMethod.POST || method == Leaf.xNet.HttpMethod.PATCH || method == Leaf.xNet.HttpMethod.PUT || method == Leaf.xNet.HttpMethod.DELETE;

            while (true)
            {
                try
                {
                    DiscordHttpResponse resp;

                    if (_discordClient.Proxy == null || _discordClient.Proxy.Type == ProxyType.HTTP)
                    {
                        HttpClient client = new HttpClient(new HttpClientHandler()
                        {
                            Proxy = _discordClient.Proxy == null ? null : new WebProxy(_discordClient.Proxy.Host, _discordClient.Proxy.Port)
                        });
                        if (_discordClient.Token != null)
                        {
                            client.DefaultRequestHeaders.Add("Authorization", _discordClient.Token);
                        }

                        if (_discordClient.User != null && _discordClient.User.Type == DiscordUserType.Bot)
                        {
                            client.DefaultRequestHeaders.Add("User-Agent", "Anarchy/0.8.1.0");
                        }
                        else
                        {
                            client.DefaultRequestHeaders.Add("User-Agent", _discordClient.Config.SuperProperties.UserAgent);
                            client.DefaultRequestHeaders.Add("X-Super-Properties", _discordClient.Config.SuperProperties.ToBase64());
                        }

                        var response = await client.SendAsync(new HttpRequestMessage()
                        {
                            Content    = hasData ? new System.Net.Http.StringContent(json, Encoding.UTF8, "application/json") : null,
                            Method     = new System.Net.Http.HttpMethod(method.ToString()),
                            RequestUri = new Uri(endpoint)
                        });

                        resp = new DiscordHttpResponse((int)response.StatusCode, response.Content.ReadAsStringAsync().Result);
                    }
                    else
                    {
                        HttpRequest msg = new HttpRequest
                        {
                            IgnoreProtocolErrors = true,
                            UserAgent            = _discordClient.User != null && _discordClient.User.Type == DiscordUserType.Bot ? "Anarchy/0.8.1.0" : _discordClient.Config.SuperProperties.UserAgent,
                            Authorization        = _discordClient.Token
                        };

                        if (hasData)
                        {
                            msg.AddHeader(HttpHeader.ContentType, "application/json");
                        }

                        if (_discordClient.User == null || _discordClient.User.Type == DiscordUserType.User)
                        {
                            msg.AddHeader("X-Super-Properties", _discordClient.Config.SuperProperties.ToBase64());
                        }
                        if (_discordClient.Proxy != null)
                        {
                            msg.Proxy = _discordClient.Proxy;
                        }

                        var response = msg.Raw(method, endpoint, hasData ? new Leaf.xNet.StringContent(json) : null);

                        resp = new DiscordHttpResponse((int)response.StatusCode, response.ToString());
                    }

                    DiscordHttpUtil.ValidateResponse(resp.StatusCode, resp.Body);
                    return(resp);
                }
                catch (Exception ex) when(ex is HttpException || ex is HttpRequestException || ex is TaskCanceledException)
                {
                    if (retriesLeft == 0)
                    {
                        throw new DiscordConnectionException();
                    }

                    retriesLeft--;
                }
                catch (RateLimitException ex)
                {
                    if (_discordClient.Config.RetryOnRateLimit)
                    {
                        Thread.Sleep(ex.RetryAfter);
                    }
                    else
                    {
                        throw;
                    }
                }
            }
        }