get(get_class(), 'lock_bypage')) { $key .= '_' . md5($itemkey); } // Add user-specific identifier if(Config::inst()->get(get_class(), 'lock_byuserip') && Controller::has_curr()) { $ip = Controller::curr()->getRequest()->getIP(); $key .= '_' . md5($ip); } return $key; } public function getContent($key, $callback) { // Bypass rate limiting if flushing, or timeout isn't set $timeout = Config::inst()->get(get_class(), 'lock_timeout'); if(isset($_GET['flush']) || !$timeout) { return parent::getContent($key, $callback); } // Generate result with rate limiting enabled $limitKey = $this->getCacheKey($key); $cache = $this->getCache(); if($cacheBegin = $cache->load($limitKey)) { if(time() - $cacheBegin < $timeout) { // Politely inform visitor of limit $response = new SS_HTTPResponse_Exception('Too Many Requests.', 429); $response->getResponse()->addHeader('Retry-After', 1 + time() - $cacheBegin); throw $response; } } // Generate result with rate limit locked $cache->save(time(), $limitKey); $result = parent::getContent($key, $callback); $cache->remove($limitKey); return $result; } }