private function check($isAuthenticated = false) { static::validate(static::$unit); $timeUnit = static::$units[static::$unit]; $maxPerUnit = $isAuthenticated ? static::$authenticatedUsagePerUnit : static::$usagePerUnit; $id = User::getUniqueId(); $lastRequest = $this->restler->cache->get($id, true) ?: array('time' => 0, 'used' => 0); $diff = time() - $lastRequest['time']; # in seconds $used = $lastRequest['used']; header("X-RateLimit-Limit: {$maxPerUnit} per " . static::$unit); if ($diff >= $timeUnit) { $used = 0; } elseif ($used >= $maxPerUnit) { header("X-RateLimit-Remaining: 0"); $wait = $timeUnit - $diff % $timeUnit; sleep(1); throw new RestException(429, 'Rate limit of ' . $maxPerUnit . ' requests per ' . static::$unit . ' exceeded. Please wait for ' . static::duration($wait) . '.'); } else { $used++; } $remainingPerUnit = $maxPerUnit - $used; header("X-RateLimit-Remaining: {$remainingPerUnit}"); $this->restler->cache->set($id, array('time' => time(), 'used' => $used)); return true; }
/** * Get the form key * * @param string $method http method for form key * @param string $action relative path from the web root. When set to null * it uses the current api method's path * * @return string generated form key */ public static function key($method = 'POST', $action = null) { if (is_null($action)) { $action = Scope::get('Restler')->url; } $target = "{$method} {$action}"; if (empty(static::$key[$target])) { static::$key[$target] = md5($target . User::getIpAddress() . uniqid(mt_rand())); } $_SESSION[static::FORM_KEY] = static::$key; return static::$key[$target]; }