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 ($lockedUntil = $cache->load($limitKey)) { if (time() < $lockedUntil) { // Politely inform visitor of limit $response = new \SS_HTTPResponse_Exception('Too Many Requests.', 429); $response->getResponse()->addHeader('Retry-After', 1 + $lockedUntil - time()); throw $response; } } // Apply rate limit $cache->save(time() + $timeout, $limitKey); // Generate results $result = parent::getContent($key, $callback); // Reset rate limit with optional cooldown if ($cooldown = \Config::inst()->get(get_class(), 'lock_cooldown')) { // Set cooldown on successful query execution $cache->save(time() + $cooldown, $limitKey); } else { // Without cooldown simply disable lock $cache->remove($limitKey); } return $result; }
public function onAfterInit() { /* * Custom handler to redirect invalid url's to the home page, so we never have a 404 error * will first check if there is already a redirect provided for a specific page */ if ($this->owner->ErrorCode == 404) { $RedirectPage = $this->FindRedirectPage(); $response = new SS_HTTPResponse_Exception(); $response->getResponse()->redirect($RedirectPage ? $RedirectPage->Link() : "/", 301); throw $response; } }
/** * Gets the video by it's url * @param {string} $url Vidyard Video URL to lookup * @return {array} Array in which the first key is a file instance and the second key is the url */ protected function getVideoByURL($url) { //Get the video id $videoID = Vidyard::getVidyardCode($url); if (empty($videoID)) { $exception = new SS_HTTPResponse_Exception('Could not get the Video ID from the URL', 400); $exception->getResponse()->addHeader('X-Status', $exception->getMessage()); throw $exception; } //Retrieve and Check the api key $apiKey = Vidyard::config()->api_key; if (empty($apiKey)) { $exception = new SS_HTTPResponse_Exception('Vidyard.api_key is not set, please configure your api key see http://support.vidyard.com/articles/Public_Support/Using-the-Vidyard-dashboard-API/ for how to get your API key.', 401); $exception->getResponse()->addHeader('X-Status', $exception->getMessage()); throw $exception; } return array(new File(array('Title' => $videoID, 'Filename' => trim($url))), trim($url)); }
/** * Gets the overview data from new relic */ public function overview_data() { //Purge Requirements Requirements::clear(); //If we're not configured properly return an error if (!$this->getIsConfigured()) { $msg = _t('NewRelicPerformanceReport.API_APP_CONFIG_ERROR', '_New Relic API Key or Application ID is missing, check configuration'); $e = new SS_HTTPResponse_Exception($msg, 400); $e->getResponse()->addHeader('Content-Type', 'text/plain'); $e->getResponse()->addHeader('X-Status', rawurlencode($msg)); throw $e; return; } //Build the base restful service object $service = new RestfulService('https://api.newrelic.com/v2/applications/' . Convert::raw2url($this->config()->application_id) . '/metrics/data.json', $this->config()->refresh_rate); $service->httpHeader('X-Api-Key:' . Convert::raw2url($this->config()->api_key)); //Perform the request $response = $service->request('', 'POST', 'names[]=HttpDispatcher&names[]=Apdex&names[]=EndUser/Apdex&names[]=Errors/all&names[]=EndUser&period=60'); //Retrieve the body $body = $response->getBody(); if (!empty($body)) { $this->response->addHeader('Content-Type', 'application/json; charset=utf-8'); return $body; } //Data failed to load $msg = _t('NewRelicPerformanceReport.DATA_LOAD_FAIL', '_Failed to retrieve data from New Relic'); $e = new SS_HTTPResponse_Exception($msg, 400); $e->getResponse()->addHeader('Content-Type', 'text/plain'); $e->getResponse()->addHeader('X-Status', rawurlencode($msg)); throw $e; }
/** * Confirm that the current page is valid. */ public function validate() { $parent = $this->getParent(); // The URL segment will conflict with a year/month/day/media format when numeric. if (is_numeric($this->URLSegment) || !$parent instanceof MediaHolder || $this->MediaTypeID && $parent->MediaTypeID != $this->MediaTypeID) { // Customise a validation error message. $message = is_numeric($this->URLSegment) ? '"URL Segment" must not be numeric!' : 'Invalid media holder!'; $error = new SS_HTTPResponse_Exception($message, 403); $error->getResponse()->addHeader('X-Status', rawurlencode($message)); // Allow extension customisation. $this->extend('validateMediaPage', $error); throw $error; } return parent::validate(); }
/** * Throws a HTTP error response encased in a {@link SS_HTTPResponse_Exception}, which is later caught in * {@link RequestHandler::handleAction()} and returned to the user. * * @param int $errorCode * @param string $errorMessage Plaintext error message * @uses SS_HTTPResponse_Exception */ public function httpError($errorCode, $errorMessage = null) { $e = new SS_HTTPResponse_Exception($errorMessage, $errorCode); // Error responses should always be considered plaintext, for security reasons $e->getResponse()->addHeader('Content-Type', 'text/plain'); throw $e; }
public function handleRequest(SS_HTTPRequest $request, DataModel $model = null) { try { $response = parent::handleRequest($request, $model); } catch (ValidationException $e) { // Nicer presentation of model-level validation errors $msgs = _t('LeftAndMain.ValidationError', 'Validation error') . ': ' . $e->getMessage(); $e = new SS_HTTPResponse_Exception($msgs, 403); $e->getResponse()->addHeader('Content-Type', 'text/plain'); $e->getResponse()->addHeader('X-Status', rawurlencode($msgs)); throw $e; } $title = $this->Title(); if (!$response->getHeader('X-Controller')) { $response->addHeader('X-Controller', $this->class); } if (!$response->getHeader('X-Title')) { $response->addHeader('X-Title', urlencode($title)); } // Prevent clickjacking, see https://developer.mozilla.org/en-US/docs/HTTP/X-Frame-Options $this->response->addHeader('X-Frame-Options', 'SAMEORIGIN'); return $response; }
/** * Prepare error for the front end * * @param string $message * @param int $code * @return SS_HTTPResponse_Exception */ protected function getErrorFor($message, $code = 400) { $exception = new SS_HTTPResponse_Exception($message, $code); $exception->getResponse()->addHeader('X-Status', $message); return $exception; }
protected function viewfile_getRemoteFileByURL($fileUrl) { $scheme = strtolower(parse_url($fileUrl, PHP_URL_SCHEME)); $allowed_schemes = self::config()->fileurl_scheme_whitelist; if (!$scheme || $allowed_schemes && !in_array($scheme, $allowed_schemes)) { $exception = new SS_HTTPResponse_Exception("This file scheme is not included in the whitelist", 400); $exception->getResponse()->addHeader('X-Status', $exception->getMessage()); throw $exception; } $domain = strtolower(parse_url($fileUrl, PHP_URL_HOST)); $allowed_domains = self::config()->fileurl_domain_whitelist; if (!$domain || $allowed_domains && !in_array($domain, $allowed_domains)) { $exception = new SS_HTTPResponse_Exception("This file hostname is not included in the whitelist", 400); $exception->getResponse()->addHeader('X-Status', $exception->getMessage()); throw $exception; } return array(new File(array('Title' => basename($fileUrl), 'Filename' => $fileUrl)), $fileUrl); }
public function respondWithError($args) { // Make args' keys lowercase $args = array_combine(array_map('strtolower', array_keys($args)), array_values($args)); // See if an exception is passed (no default) $exception = null; if (isset($args['exception'])) { $exception = $args['exception']; } // Get the default exception noun if set $exceptionNoun = self::$exception_noun; // Add defaults $args = array_merge(array('code' => 500, 'description' => null, 'body' => null, 'noun' => $exception && $exceptionNoun ? new $exceptionNoun($exception) : null), $args); // Default "response" which we build into. Not returned, because the exception has it's own response $response = new SS_HTTPResponse(); // If there's a formatter if ($args['noun'] && ($formatter = RESTFormatter::get_formatter($this->request))) { // Format the response. Revert back to default response if we got nothing. $response = $formatter->format($args['noun'], array('*')); if (!$response) { $response = new SS_HTTPResponse(); } } else { if ($exception) { $exception = $args['exception']; $response->setBody($exception->getMessage() . "\n"); $response->addHeader('Content-Type', 'text/plain'); } } // If a specific body was provided, use that if ($args['body']) { $response->setBody($args['body']); } // Build an exception with those details $e = new SS_HTTPResponse_Exception($response->getBody(), $args['code'], $args['description']); $exceptionResponse = $e->getResponse(); // Add user specified headers foreach ($response->getHeaders() as $k => $v) { $exceptionResponse->addHeader($k, $v); } throw $e; }