示例#1
0
 private static void HandleFailure(TwitterAPIEndpoint endpoint, UserRateLimitInfo userStatus, AuthenticationType?authTypeUsed, HttpResponseMessage response)
 {
     if (!response.IsSuccessStatusCode)
     {
         if (authTypeUsed.Value == AuthenticationType.Application)
         {
             RateLimitCache.Get[endpoint].Update(RateLimitCache.Get[endpoint].Limit - 1);
         }
         else
         {
             userStatus?.Update(userStatus.Limit - 1);
         }
     }
 }
示例#2
0
 private static void UpdateRateLimits(TwitterAPIEndpoint endpoint, UserRateLimitInfo userStatus, AuthenticationType?authTypeUsed, HttpResponseMessage response)
 {
     if (response.Headers.TryGetValues("x-rate-limit-remaining", out IEnumerable <string> remaining) &&
         response.Headers.TryGetValues("x-rate-limit-reset", out IEnumerable <string> reset))
     {
         if (int.TryParse(remaining.FirstOrDefault(), out int limitRemaining) &&
             double.TryParse(reset.FirstOrDefault(), out double secondsUntilReset))
         {
             if (authTypeUsed.Value == AuthenticationType.Application)
             {
                 RateLimitCache.Get[endpoint].Update(limitRemaining, UntilEpochSeconds(secondsUntilReset));
             }
             else
             {
                 userStatus?.Update(limitRemaining, UntilEpochSeconds(secondsUntilReset));
             }
         }
     }
 }
示例#3
0
 private static bool UseUserAuth(AuthenticationType authType, string token, UserRateLimitInfo userStatus)
 {
     return(userStatus != null && userStatus.Available && token != null &&
            (authType == AuthenticationType.User || authType == AuthenticationType.Both));
 }
示例#4
0
 private static bool UseApplicationAuth(AuthenticationType authType, string token, AppRateLimitInfo appStatus, UserRateLimitInfo userStatus)
 {
     return(appStatus.Available &&
            (authType == AuthenticationType.Application ||
             (authType == AuthenticationType.Both && (null == token || !userStatus.Available))));
 }
示例#5
0
 private static bool TryAuthorize(HttpRequestMessage request, IConfiguration config, AuthenticationType authType, string token, string tokenSecret, AppRateLimitInfo appStatus, UserRateLimitInfo userStatus, out AuthenticationType?used)
 {
     if (UseApplicationAuth(authType, token, appStatus, userStatus))
     {
         AddBearerAuth(config, request);
         used = AuthenticationType.Application;
     }
     else if (UseUserAuth(authType, token, userStatus))
     {
         AddUserAuth(config, request, token, tokenSecret);
         used = AuthenticationType.User;
     }
     else
     {
         used = null;
         return(false);
     }
     return(true);
 }
示例#6
0
        /// <summary>
        /// Attempts to authenticate a call to the Twitter API with the given query string and authentication info. Updates rate limits if applicable.
        /// </summary>
        /// <param name="config"></param>
        /// <param name="authType"></param>
        /// <param name="endpoint"></param>
        /// <param name="query"></param>
        /// <param name="token"></param>
        /// <param name="tokenSecret"></param>
        /// <param name="userStatus"></param>
        /// <returns></returns>
        internal static async Task <string> GetResponse(IConfiguration config, AuthenticationType authType, TwitterAPIEndpoint endpoint,
                                                        string query, string token, string tokenSecret, UserRateLimitInfo userStatus)
        {
            // Yep, that's a lot of parameters.
            AppRateLimitInfo appStatus = RateLimitCache.Get[endpoint];

            if (!appStatus.Available)
            {
                throw new Exception($"Endpoint {endpoint} currently unavailable due to rate limits. Time until reset: {appStatus.UntilReset}");
            }
            appStatus.ResetIfNeeded();
            try
            {
                using (var client = new HttpClient())
                    using (var request = new HttpRequestMessage(HttpMethod(endpoint), GetUri(endpoint, query)))
                    {
                        if (!TryAuthorize(request, config, authType, token, tokenSecret, appStatus, userStatus, out AuthenticationType? authTypeUsed))
                        {
                            throw new Exception($"Unable to authenticate Twitter API call of type {authType}, endpoint {endpoint}.");
                        }
                        using (HttpResponseMessage response = await client.SendAsync(request, HttpCompletionOption.ResponseContentRead))
                        {
                            HandleFailure(endpoint, userStatus, authTypeUsed, response);
                            response.EnsureSuccessStatusCode();
                            UpdateRateLimits(endpoint, userStatus, authTypeUsed, response);
                            return(await response.Content.ReadAsStringAsync());
                        }
                    }
            }
            catch (Exception ex)
            {
                throw new Exception($"Twitter API call failed: {ex.Message}");
            }
        }