/// <summary> /// Получает объект кэша по token /// </summary> /// Если объект не доступен в кэше. /// Объект будет загружен из базы, и помещен в кэш. /// <param name="guid">Токен клиента</param> /// <returns>Объект кэша</returns> public MorpherCacheObject GetQueryLimit(Guid guid) { object obj = _morpherCache.Get(guid.ToString().ToLowerInvariant()); if (obj != null) { return((MorpherCacheObject)obj); } // Если объекта нет в кэше, нужно проверить его в бд. MorpherCacheObject morpherCacheObject = _morpherDatabase.GetUserLimits(guid); if (morpherCacheObject == null) { return(null); } if (morpherCacheObject.Unlimited) { morpherCacheObject.QueriesLeft = 1000; } _morpherCache.Set(guid.ToString().ToLowerInvariant(), morpherCacheObject, _absoluteExpiration); return(morpherCacheObject); }
public void Log(IOwinContext context) { string remoteAddress = context.Request.RemoteIpAddress; string queryString = HttpUtility.UrlDecode(context.Request.QueryString.ToString()); string urlPath = context.Request.Path.ToString(); string userAgent = context.Request.Headers.Get("User-Agent"); int errorCode; int.TryParse(context.Response.Headers.Get("Error-code"), out errorCode); Guid?token = null; MorpherCacheObject cacheObject = null; if (errorCode != new InvalidTokenFormatException().Code) { token = context.Request.GetToken(); if (token != null) { cacheObject = (MorpherCacheObject)_morpherCache.Get(token.ToString().ToLowerInvariant()); } } _logQueue.Enqueue( new LogEntity(remoteAddress, queryString, urlPath, DateTime.UtcNow, token, cacheObject?.UserId, userAgent, errorCode)); }
/// <summary> /// Получает объет кэша по ip. /// </summary> /// <param name="ip">ip клиента</param> /// <returns>Запись в кэше; Если ip заблокирован - значение null.</returns> public MorpherCacheObject GetQueryLimit(string ip) { object cache = _morpherCache.Get(ip); if (cache != null) { return((MorpherCacheObject)cache); } if (_morpherDatabase.IsIpBlocked(ip)) { return(null); } int limit = _morpherDatabase.GetDefaultDailyQueryLimit(); // Записываем объект в кэш. MorpherCacheObject morpherCacheObject = new MorpherCacheObject() { QueriesLeft = limit, PaidUser = false, Unlimited = false }; _morpherCache.Set(ip, morpherCacheObject, _absoluteExpiration); return(morpherCacheObject); }
public HttpResponseMessage QueriesLeftToday(ResponseFormat?format = null) { var guid = Request.GetToken(); MorpherCacheObject cacheObject = null; if (guid == null) { cacheObject = _apiThrottler.GetQueryLimit(Request.GetClientIp()); if (cacheObject == null) { return(Request.CreateResponse( HttpStatusCode.OK, new ServiceErrorMessage(new IpBlockedException()), format)); } } else { cacheObject = _apiThrottler.GetQueryLimit(guid.Value); if (cacheObject == null) { return(Request.CreateResponse( HttpStatusCode.OK, new ServiceErrorMessage(new TokenNotFoundException()), format)); } } return(Request.CreateResponse(HttpStatusCode.OK, Math.Max(cacheObject.QueriesLeft, 0), format)); }
/// <summary> /// Выполняет тарификацию по IP адресу /// </summary> /// <param name="ip">ip адрес клиента</param> /// <returns>Результат тарификации</returns> public ApiThrottlingResult Throttle(string ip, int cost) { MorpherCacheObject morpherCacheObject = GetQueryLimit(ip); // Если GetQueryLimit вернул null, значит IP адрес помечен в бд как Blocked if (morpherCacheObject == null) { return(ApiThrottlingResult.IpBlocked); } return(Charge(morpherCacheObject, cost)); }
/// <summary> /// Выполняет тарификацию по токену /// </summary> /// <param name="guid">Токен клиента</param> /// <returns>Результат тарификации</returns> public ApiThrottlingResult Throttle(Guid guid, int cost) { MorpherCacheObject morpherCacheObject = GetQueryLimit(guid); // Если morpherCacheObject null, то токен не был найден в кэше, или бд. if (morpherCacheObject == null) { return(ApiThrottlingResult.TokenNotFound); } if (morpherCacheObject.Unlimited) { return(ApiThrottlingResult.Success); } return(Charge(morpherCacheObject, cost)); }
static ApiThrottlingResult Charge(MorpherCacheObject morpherCacheObject, int cost) { return(Interlocked.Add(ref morpherCacheObject.QueriesLeft, -cost) >= 0 ? ApiThrottlingResult.Success : ApiThrottlingResult.Overlimit); }