public function httpError($code, $message = null) { $response = new SS_HTTPResponse(); $response->setStatusCode($code); $response->addHeader('Content-Type', 'text/html'); return $response; }
/** * Returns the unread count in a JSONobject * * @return SS_HTTPResponse */ public function count() { $notifications = TimelineEvent::get_unread(Member::currentUser()); $response = new SS_HTTPResponse(json_encode(array('count' => $notifications->count())), 200); $response->addHeader('Content-Type', 'application/json'); return $response; }
public function testAddCacheHeaders() { $body = "<html><head></head><body><h1>Mysite</h1></body></html>"; $response = new SS_HTTPResponse($body, 200); $this->assertEmpty($response->getHeader('Cache-Control')); HTTP::set_cache_age(30); HTTP::add_cache_headers($response); $this->assertNotEmpty($response->getHeader('Cache-Control')); // Ensure max-age is zero for development. Config::inst()->update('Director', 'environment_type', 'dev'); $response = new SS_HTTPResponse($body, 200); HTTP::add_cache_headers($response); $this->assertContains('max-age=0', $response->getHeader('Cache-Control')); // Ensure max-age setting is respected in production. Config::inst()->update('Director', 'environment_type', 'live'); $response = new SS_HTTPResponse($body, 200); HTTP::add_cache_headers($response); $this->assertContains('max-age=30', explode(', ', $response->getHeader('Cache-Control'))); $this->assertNotContains('max-age=0', $response->getHeader('Cache-Control')); // Still "live": Ensure header's aren't overridden if already set (using purposefully different values). $headers = array('Vary' => '*', 'Pragma' => 'no-cache', 'Cache-Control' => 'max-age=0, no-cache, no-store'); $response = new SS_HTTPResponse($body, 200); foreach ($headers as $name => $value) { $response->addHeader($name, $value); } HTTP::add_cache_headers($response); foreach ($headers as $name => $value) { $this->assertEquals($value, $response->getHeader($name)); } }
public function postRequest(\SS_HTTPRequest $request, \SS_HTTPResponse $response, \DataModel $model) { if ($this->convertUrls && $response && $response->getStatusCode() == 200) { // only convert if we have an HTML content type response $body = $response->getBody(); // find urls inserted in content if (strpos($body, 'cdnfileid') > 0 && preg_match_all('/data-cdnfileid="(\\d+)"/', $body, $matches)) { $files = CdnImage::get()->filter('ID', $matches[1]); $fileIds = array(); foreach ($files as $file) { $url = $file->getUrl(); $filename = $file->Filename; $body = str_replace("src=\"{$filename}\"", "src=\"{$url}\"", $body); $fileIds[] = $file->ID; } $assets = ContentServiceAsset::get()->filter('SourceID', $matches[1]); foreach ($assets as $asset) { $url = $asset->getUrl(); $filename = $asset->Filename; // note the extra forward slash here, image_cached inserts it $body = str_replace("src=\"/{$filename}\"", "src=\"{$url}\"", $body); } $response->setBody($body); } } }
/** * Action to handle upload of a single file * * @param SS_HTTPRequest $request * @return SS_HTTPResponse * @return SS_HTTPResponse */ public function upload(SS_HTTPRequest $request) { if ($this->isDisabled() || $this->isReadonly() || !$this->canUpload()) { return $this->httpError(403); } // Protect against CSRF on destructive action $token = $this->getForm()->getSecurityToken(); if (!$token->checkRequest($request)) { return $this->httpError(400); } // Get form details $name = $this->getName(); $postVars = $request->postVar($name); // Save the temporary file into a File object $uploadedFiles = $this->extractUploadedFileData($postVars); $firstFile = reset($uploadedFiles); $file = $this->saveTemporaryFile($firstFile, $error); if (empty($file)) { $return = array('error' => $error); } else { $return = $this->encodeFileAttributes($file); } // Format response with json $response = new SS_HTTPResponse(Convert::raw2json(array($return))); $response->addHeader('Content-Type', 'text/plain'); if (!empty($return['error'])) { $response->setStatusCode(200); } return $response; }
public function handleRequest(SS_HTTPRequest $request, DataModel $model = NULL) { $body = null; $lang = i18n::get_locale(); $path = Config::inst()->get('UniversalErrorPage', 'DefaultPath'); if (!$path) { $path = $this->defaultErrorPagePath; } $forCode = Config::inst()->get('UniversalErrorPage', $this->ErrorCode); $localeForCode = preg_replace('/\\.([a-z]+)$/i', '-' . $lang . '.$1', $forCode); $errorPages = array($localeForCode, $forCode, $path . "error-{$this->ErrorCode}-{$lang}.html", $path . "error-{$this->ErrorCode}-{$lang}.php", $path . "error-{$lang}.html", $path . "error-{$lang}.php", $path . 'error.html', $path . 'error.php'); $this->extend('updateHandleRequest', $errorPages); // now check if any of the pages exist foreach ($errorPages as $errorPage) { if (!$body && file_exists($errorPage)) { $ext = pathinfo($errorPage, PATHINFO_EXTENSION); if ($ext == 'php') { ob_start(); include $errorPage; $body = ob_get_clean(); } else { $body = file_get_contents($errorPage); } break; } } if ($body) { $response = new SS_HTTPResponse(); $response->setStatusCode($this->ErrorCode); $response->setBody($body); return $response; } return parent::handleRequest($request, $model); }
public function load($request) { $response = new SS_HTTPResponse(); $response->addHeader('Content-Type', 'application/json'); $response->setBody(Convert::array2json(array("_memberID" => Member::currentUserID()))); return $response; }
public function getGoogleMapPin(SS_HTTPRequest $request) { $color = Convert::raw2sql($request->param('Color')); $path = ASSETS_PATH . '/maps/pins'; // create folder on assets if does not exists .... if (!is_dir($path)) { mkdir($path, $mode = 0775, $recursive = true); } // if not get it from google (default) $ping_url = "http://chart.apis.google.com/chart?cht=mm&chs=32x32&chco=FFFFFF,{$color},000000&ext=.png"; $write_2_disk = true; if (file_exists($path . '/pin_' . $color . '.jpg')) { // if we have the file on assets use it $ping_url = $path . '/pin_' . $color . '.jpg'; $write_2_disk = false; } $body = file_get_contents($ping_url); if ($write_2_disk) { file_put_contents($path . '/pin_' . $color . '.jpg', $body); } $ext = 'jpg'; $response = new SS_HTTPResponse($body, 200); $response->addHeader('Content-Type', 'image/' . $ext); return $response; }
public function postRequest(\SS_HTTPRequest $request, \SS_HTTPResponse $response, \DataModel $model) { if (defined('PROXY_CACHE_GENERATING') || isset($GLOBALS['__cache_publish']) || strpos($request->getURL(), 'admin/') !== false) { return; } $this->database = Db::getConn(); $queries = $this->database->queryRecord; $dupes = $this->database->getDuplicateQueries(); $str = "\n<!-- Total queries: " . count($queries) . "-->\n"; $str .= "\n<!-- Duplicate queries: " . count($dupes) . "-->\n"; $b = $response->getBody(); if (strpos($b, '</html>')) { if (count($queries) > $this->queryThreshold) { // add a floating div with info about the stuff $buildQueryList = function ($source, $class) { $html = ''; foreach ($source as $sql => $info) { $html .= "\n<p class='{$class}' style='display: none; border-top: 1px dashed #000;'>{$info->count} : {$info->query}</p>\n"; if ($info->source) { $html .= "\n<p class='{$class}' style='color: #a00; display: none; '>Last called from {$info->source}</p>\n"; } } return $html; }; $html = $buildQueryList($queries, 'debug-query'); $html .= $buildQueryList($dupes, 'debug-dupe-query'); $div = '<div id="query-stat-debugger" ' . 'style="position: fixed; bottom: 0; right: 0; border: 2px solid red; background: #fff; ' . 'font-size: 8px; font-family: sans-serif; width: 100px; z-index: 2000; padding: 1em;' . 'overflow: auto; max-height: 500px;">' . '<p id="debug-all-queries-list">Total of ' . count($queries) . ' queries</p>' . '<p id="debug-dupe-queries-list">Total of ' . count($dupes) . ' duplicates</p>' . $html . '<script>' . 'jQuery("#debug-all-queries-list").click(function () {' . 'var elems = jQuery(this).parent().find(".debug-query");' . 'jQuery(this).parent().css("width", "40%");' . 'elems.toggle();' . '}); ' . 'jQuery("#debug-dupe-queries-list").click(function () {' . 'var elems = jQuery(this).parent().find(".debug-dupe-query");' . 'jQuery(this).parent().css("width", "40%");' . 'elems.toggle();' . '}); ' . '' . '' . '</script>' . '</div>'; $b = str_replace('</body>', "{$div}</body>", $b); } $b = str_replace('</html>', "{$str}</html>", $b); $response->setBody($b); } }
public function load($request) { $response = new SS_HTTPResponse(); $response->addHeader('Content-Type', 'application/json'); $response->setBody(Convert::array2json(call_user_func($this->source, $request->getVar('val')))); return $response; }
/** * Use cURL to request a URL, and return a SS_HTTPResponse object. */ protected function curlRequest($url, $method, $data = null, $headers = null, $curlOptions = array()) { $ch = curl_init(); $timeout = 5; $ssInfo = new SapphireInfo(); $useragent = 'SilverStripe/' . $ssInfo->version(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_USERAGENT, $useragent); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); curl_setopt($ch, CURLOPT_HEADER, 1); if ($headers) { curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); } // Add fields to POST and PUT requests if ($method == 'POST') { curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); } elseif ($method == 'PUT') { $put = fopen("php://temp", 'r+'); fwrite($put, $data); fseek($put, 0); curl_setopt($ch, CURLOPT_PUT, 1); curl_setopt($ch, CURLOPT_INFILE, $put); curl_setopt($ch, CURLOPT_INFILESIZE, strlen($data)); } // Follow redirects curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE); // Set any custom options passed to the request() function curl_setopt_array($ch, $curlOptions); // Run request curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $fullResponseBody = curl_exec($ch); $curlError = curl_error($ch); list($responseHeaders, $responseBody) = preg_split('/(\\n\\r?){2}/', $fullResponseBody, 2); if (preg_match("#^HTTP/1.1 100#", $responseHeaders)) { list($responseHeaders, $responseBody) = preg_split('/(\\n\\r?){2}/', $responseBody, 2); } $responseHeaders = explode("\n", trim($responseHeaders)); array_shift($responseHeaders); $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($curlError !== '' || $statusCode == 0) { $statusCode = 500; } $response = new SS_HTTPResponse($responseBody, $statusCode); foreach ($responseHeaders as $headerLine) { if (strpos($headerLine, ":") !== false) { list($headerName, $headerVal) = explode(":", $headerLine, 2); // This header isn't relevant outside of curlRequest if (strtolower($headerName) == 'transfer-encoding') { continue; } $response->addHeader(trim($headerName), trim($headerVal)); } } curl_close($ch); return $response; }
function Places() { $Places = DataObject::get("Place"); $body = $this->owner->customise(array('Places' => $Places))->renderWith("KMLPlaces"); $response = new SS_HTTPResponse($body, 200); $response->addHeader('Content-type', "application/vnd.google-earth.kml+xml"); return $response; }
function testContentLengthHeader() { $r = new SS_HTTPResponse('123ü'); $this->assertNotNull($r->getHeader('Content-Length'), 'Content-length header is added'); $this->assertEquals(5, $r->getHeader('Content-Length'), 'Header matches actual content length in bytes'); $r->setBody('1234ü'); $this->assertEquals(6, $r->getHeader('Content-Length'), 'Header is updated when body is changed'); }
/** * Returns a JSON string of tags, for lazy loading. * * @param SS_HTTPRequest $request * * @return SS_HTTPResponse */ public function suggest(SS_HTTPRequest $request) { $members = $this->getMembers($request->getVar('term')); $response = new SS_HTTPResponse(); $response->addHeader('Content-Type', 'application/json'); $response->setBody(json_encode($members)); return $response; }
/** * Unlink the selected records passed from the unlink bulk action. * * @param SS_HTTPRequest $request * * @return SS_HTTPResponse List of affected records ID */ public function unLink(SS_HTTPRequest $request) { $ids = $this->getRecordIDList(); $this->gridField->list->removeMany($ids); $response = new SS_HTTPResponse(Convert::raw2json(array('done' => true, 'records' => $ids))); $response->addHeader('Content-Type', 'text/json'); return $response; }
/** * @param \SS_HTTPRequest $request * @return null|\SS_HTTPResponse */ public function getResponse(\SS_HTTPRequest $request) { if ($redirect = $this->getRedirectForRequest($request)) { $response = new \SS_HTTPResponse(); $response->redirect($redirect->getTo(), $redirect->getStatusCode()); return $response; } return null; }
public function postRequest(SS_HTTPRequest $request, SS_HTTPResponse $response, DataModel $model) { if (!$response->isError() && !Director::is_ajax()) { // Find or create the visitor record $visitor = Visitor::initVisitor(); // Log the arrival of this visitor to this page $visitor->logPageArrival(); } }
/** * Filter executed AFTER a request * * @param SS_HTTPRequest $request Request container object * @param SS_HTTPResponse $response Response output object * @param DataModel $model Current DataModel * @return boolean Whether to continue processing other filters. Null or true will continue processing (optional) */ public function postRequest(SS_HTTPRequest $request, SS_HTTPResponse $response, DataModel $model) { if (!self::isEnabled()) { return true; } $body = $response->getBody(); $response->setBody(self::replaceCDN($body)); return true; }
/** * @param Object $originator * @param SS_HTTPRequest $request * @param SS_HTTPResponse $response * @param DataModel $model */ public function applyToResponse($originator, SS_HTTPRequest $request, SS_HTTPResponse $response, DataModel $model) { foreach ($this->headers as $key => $value) { if ($value !== "") { $response->addHeader($key, $value); } else { $response->removeHeader($key); } } }
public function postRequest(\SS_HTTPRequest $request, \SS_HTTPResponse $response, \DataModel $model) { $time = sprintf('%.3f ms', microtime(true) - $this->start); $response->addHeader('X-SilverStripe-Time', $time); $b = $response->getBody(); if (strpos($b, '</html>')) { $b = str_replace('</html>', "\n<!-- Generated in {$time} -->\n</html>", $b); $response->setBody($b); } }
/** * Require basic authentication. Will request a username and password if none is given. * * Used by {@link Controller::init()}. * * @throws SS_HTTPResponse_Exception * * @param string $realm * @param string|array $permissionCode Optional * @param boolean $tryUsingSessionLogin If true, then the method with authenticate against the * session log-in if those credentials are disabled. * @return Member $member */ public static function requireLogin($realm, $permissionCode = null, $tryUsingSessionLogin = true) { $isRunningTests = class_exists('SapphireTest', false) && SapphireTest::is_running_test(); if (!Security::database_is_ready() || Director::is_cli() && !$isRunningTests) { return true; } /* * Enable HTTP Basic authentication workaround for PHP running in CGI mode with Apache * Depending on server configuration the auth header may be in HTTP_AUTHORIZATION or * REDIRECT_HTTP_AUTHORIZATION * * The follow rewrite rule must be in the sites .htaccess file to enable this workaround * RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] */ $authHeader = isset($_SERVER['HTTP_AUTHORIZATION']) ? $_SERVER['HTTP_AUTHORIZATION'] : (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) ? $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] : null); $matches = array(); if ($authHeader && preg_match('/Basic\\s+(.*)$/i', $authHeader, $matches)) { list($name, $password) = explode(':', base64_decode($matches[1])); $_SERVER['PHP_AUTH_USER'] = strip_tags($name); $_SERVER['PHP_AUTH_PW'] = strip_tags($password); } $member = null; if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) { $member = MoreAdminsAuthenticator::authenticate(array('Email' => $_SERVER['PHP_AUTH_USER'], 'Password' => $_SERVER['PHP_AUTH_PW']), null); } if (!$member && $tryUsingSessionLogin) { $member = Member::currentUser(); } // If we've failed the authentication mechanism, then show the login form if (!$member) { $response = new SS_HTTPResponse(null, 401); $response->addHeader('WWW-Authenticate', "Basic realm=\"{$realm}\""); if (isset($_SERVER['PHP_AUTH_USER'])) { $response->setBody(_t('BasicAuth.ERRORNOTREC', "That username / password isn't recognised")); } else { $response->setBody(_t('BasicAuth.ENTERINFO', "Please enter a username and password.")); } // Exception is caught by RequestHandler->handleRequest() and will halt further execution $e = new SS_HTTPResponse_Exception(null, 401); $e->setResponse($response); throw $e; } if ($permissionCode && !Permission::checkMember($member->ID, $permissionCode)) { $response = new SS_HTTPResponse(null, 401); $response->addHeader('WWW-Authenticate', "Basic realm=\"{$realm}\""); if (isset($_SERVER['PHP_AUTH_USER'])) { $response->setBody(_t('BasicAuth.ERRORNOTADMIN', "That user is not an administrator.")); } // Exception is caught by RequestHandler->handleRequest() and will halt further execution $e = new SS_HTTPResponse_Exception(null, 401); $e->setResponse($response); throw $e; } return $member; }
public function getAndroidAssetLinksFile(SS_HTTPRequest $request) { global $APP_LINKS_ANDROID_FILE_CONFIG; $file = []; foreach ($APP_LINKS_ANDROID_FILE_CONFIG as $package => $fingerprints) { $file[] = ["relation" => ["delegate_permission/common.handle_all_urls"], "target" => ["namespace" => "android_app", "package_name" => $package, "sha256_cert_fingerprints" => $fingerprints]]; } $response = new SS_HTTPResponse(json_encode($file), 200); $response->addHeader('Content-Type', 'application/json; charset=utf-8'); return $response; }
/** * Delete the selected records passed from the delete bulk action. * * @param SS_HTTPRequest $request * * @return SS_HTTPResponse List of deleted records ID */ public function delete(SS_HTTPRequest $request) { $ids = array(); foreach ($this->getRecords() as $record) { array_push($ids, $record->ID); $record->delete(); } $response = new SS_HTTPResponse(Convert::raw2json(array('done' => true, 'records' => $ids))); $response->addHeader('Content-Type', 'text/json'); return $response; }
/** * Handles returning a JSON response, makes sure Content-Type header is set * * @param array $array * @param bool $isJson Is the passed string already a json string * @return SS_HTTPResponse */ public function jsonResponse($array, $isJson = false) { $json = $array; if (!$isJson) { $json = Convert::raw2json($array); } $response = new SS_HTTPResponse($json); $response->addHeader('Content-Type', 'application/json'); $response->addHeader('Vary', 'Accept'); return $response; }
public function doSend($data, $form) { try { $this->record->doSend(); } catch (PushException $ex) { return new SS_HTTPResponse($this->ItemEditForm()->forAjaxTemplate(), 400, $ex->getMessage()); } $response = new SS_HTTPResponse($this->ItemEditForm()->forAjaxTemplate()); $response->setStatusDescription(_t('Push.PUSHSENT', 'The push notification has been sent')); return $response; }
/** * Generates the response containing the robots.txt content * * @return SS_HTTPResponse */ public function index() { $text = ""; $text .= $this->renderSitemap(); $text .= "User-agent: *\n"; $text .= $this->renderDisallow(); $text .= $this->renderAllow(); $response = new SS_HTTPResponse($text, 200); $response->addHeader("Content-Type", "text/plain; charset=\"utf-8\""); return $response; }
/** * Process all incoming requests passed to this controller, checking * that the file exists and passing the file through if possible. */ public function handleRequest(SS_HTTPRequest $request, DataModel $model) { $response = new SS_HTTPResponse(); $filename = $request->getURL(); if (strpos($filename, 'cdnassets') === 0) { $filename = 'assets/' . substr($filename, strlen('cdnassets/')); } $file = null; if (strpos($filename, '_resampled') !== false) { $file = ContentServiceAsset::get()->filter('Filename', $filename)->first(); } else { if (strpos($filename, '/_versions/') !== false) { $file = FileVersion::get()->filter('Filename', "/" . $filename)->first(); } else { $file = File::get()->filter('filename', $filename)->first(); } } if ($file && $file->canView()) { if (!$file->CDNFile && !$file->FilePointer) { return $this->httpError(404); } // Permission passed redirect to file $redirectLink = ''; if ($file->getViewType() != CDNFile::ANYONE_PERM) { if ($file->hasMethod('getSecureURL')) { $redirectLink = $file->getSecureURL(180); } if (!strlen($redirectLink)) { // can we stream it? return $this->sendFile($file); } } else { $redirectLink = $file->getURL(); } if ($redirectLink && trim($redirectLink, '/') != $request->getURL()) { $response->redirect($redirectLink); } else { return $this->httpError(404); } } else { if (class_exists('SecureFileController')) { $handoff = SecureFileController::create(); return $handoff->handleRequest($request, $model); } elseif ($file instanceof File) { // Permission failure Security::permissionFailure($this, 'You are not authorised to access this resource. Please log in.'); } else { // File doesn't exist $response = new SS_HTTPResponse('File Not Found', 404); } } return $response; }
public function OnSitePhoneForm() { $request = Session::get('Current.PresentationSpeakerSummitAssistanceConfirmationRequest'); if (is_null($request)) { $response = new SS_HTTPResponse(); $response->setStatusCode(404); return $response; } $form = new OnSitePhoneForm($this, 'OnSitePhoneForm', $request); $form->loadDataFrom($request); return $form; }
/** * Adds Intercom script tags just before the body */ public function postRequest(SS_HTTPRequest $request, SS_HTTPResponse $response, DataModel $model) { $mime = $response->getHeader('Content-Type'); if (!$mime || strpos($mime, 'text/html') !== false) { $intercomScriptTags = (new intercomScriptTags())->forTemplate(); if ($intercomScriptTags) { $content = $response->getBody(); $content = preg_replace("/(<\\/body[^>]*>)/i", $intercomScriptTags . "\\1", $content); $response->setBody($content); } } }
public function handleAssignBulkAction($gridField, $request) { $entity_id = $request->param('EntityID'); $controller = $gridField->getForm()->Controller(); $this->gridField = $gridField; $ids = $this->getRecordIDList(); $this->processRecordIds($ids, $entity_id, $gridField, $request); $response = new SS_HTTPResponse(Convert::raw2json(array('done' => true, 'records' => $ids))); $response->addHeader('Content-Type', 'text/json'); $response->setStatusCode(200); return $response; }