/** * 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; }
/** * Actually performs a remote service request using curl. This is used by * {@link RestfulService::request()}. * * @param string $url * @param string $method * @param array $data * @param array $headers * @param array $curlOptions * @return RestfulService_Response */ public function curlRequest($url, $method, $data = null, $headers = null, $curlOptions = array()) { $ch = curl_init(); $sapphireInfo = new SapphireInfo(); $useragent = 'SilverStripe/' . $sapphireInfo->Version(); $curlOptions = $curlOptions + (array) $this->config()->default_curl_options; curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_USERAGENT, $useragent); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->getConnectTimeout()); if (!ini_get('open_basedir')) { curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); } curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); // Write headers to a temporary file $headerfd = tmpfile(); curl_setopt($ch, CURLOPT_WRITEHEADER, $headerfd); // Add headers if ($this->customHeaders) { $headers = array_merge((array) $this->customHeaders, (array) $headers); } if ($headers) { curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); } // Add authentication if ($this->authUsername) { curl_setopt($ch, CURLOPT_USERPWD, $this->getBasicAuthString()); } // 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)); } // Apply proxy settings if (is_array($this->proxy)) { curl_setopt_array($ch, $this->proxy); } // Set any custom options passed to the request() function curl_setopt_array($ch, $curlOptions); // Run request $body = curl_exec($ch); rewind($headerfd); $headers = stream_get_contents($headerfd); fclose($headerfd); $response = $this->extractResponse($ch, $headers, $body); curl_close($ch); return $response; }
/** * Makes a request to the RESTful server, and return a {@link RestfulService_Response} object for parsing of the result. * @todo Better POST, PUT, DELETE, and HEAD support * @todo Caching of requests - probably only GET and HEAD requestst * @todo JSON support in RestfulService_Response * @todo Pass the response headers to RestfulService_Response * * This is a replacement of {@link connect()}. * * @return RestfulService_Response - If curl request produces error, the returned response's status code will be 500 */ public function request($subURL = '', $method = "GET", $data = null, $headers = null, $curlOptions = array()) { $url = $this->getAbsoluteRequestURL($subURL); $method = strtoupper($method); assert(in_array($method, array('GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS'))); $cachedir = TEMP_FOLDER; // Default silverstripe cache $cache_file = md5($url); // Encoded name of cache file $cache_path = $cachedir . "/xmlresponse_{$cache_file}"; // Check for unexpired cached feed (unless flush is set) if (!isset($_GET['flush']) && @file_exists($cache_path) && @filemtime($cache_path) + $this->cache_expire > time()) { $store = file_get_contents($cache_path); $response = unserialize($store); } else { $ch = curl_init(); $timeout = 5; $useragent = "SilverStripe/" . SapphireInfo::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_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); // Add headers if ($this->customHeaders) { $headers = array_merge((array) $this->customHeaders, (array) $headers); } if ($headers) { curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); } // Add authentication if ($this->authUsername) { curl_setopt($ch, CURLOPT_USERPWD, "{$this->authUsername}:{$this->authPassword}"); } // Add fields to POST requests if ($method == 'POST') { curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); } // Apply proxy settings if (is_array($this->proxy)) { curl_setopt_array($ch, $this->proxy); } // Set any custom options passed to the request() function curl_setopt_array($ch, $curlOptions); // Run request curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $responseBody = curl_exec($ch); $curlError = curl_error($ch); // Problem verifying the server SSL certificate; just ignore it as it's not mandatory if (strpos($curlError, '14090086') !== false) { curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $responseBody = curl_exec($ch); $curlError = curl_error($ch); } $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($curlError !== '' || $statusCode == 0) { $statusCode = 500; } $response = new RestfulService_Response($responseBody, $statusCode); curl_close($ch); if ($curlError === '' && !$response->isError()) { // Serialise response object and write to cache $store = serialize($response); file_put_contents($cache_path, $store); } else { // In case of curl or/and http indicate error, populate response's cachedBody property // with cached response body with the cache file exists if (@file_exists($cache_path)) { $store = file_get_contents($cache_path); $cachedResponse = unserialize($store); $response->setCachedBody($cachedResponse->getBody()); } else { $response->setCachedBody(false); } } } return $response; }
/** * Actually performs a remote service request using curl. This is used by * {@link RestfulService::request()}. * * @param string $url * @param string $method * @param array $data * @param array $headers * @param array $curlOptions * @return RestfulService_Response */ public function curlRequest($url, $method, $data = null, $headers = null, $curlOptions = array()) { $ch = curl_init(); $timeout = 5; $sapphireInfo = new SapphireInfo(); $useragent = 'SilverStripe/' . $sapphireInfo->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); if (!ini_get('open_basedir')) { curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); } curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); // Add headers if ($this->customHeaders) { $headers = array_merge((array) $this->customHeaders, (array) $headers); } if ($headers) { curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); } // Add authentication if ($this->authUsername) { curl_setopt($ch, CURLOPT_USERPWD, "{$this->authUsername}:{$this->authPassword}"); } // 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)); } // Apply proxy settings if (is_array($this->proxy)) { curl_setopt_array($ch, $this->proxy); } // Set any custom options passed to the request() function curl_setopt_array($ch, $curlOptions); // Run request curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $responseBody = curl_exec($ch); $curlError = curl_error($ch); // Problem verifying the server SSL certificate; just ignore it as it's not mandatory if (strpos($curlError, '14090086') !== false) { curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $responseBody = curl_exec($ch); $curlError = curl_error($ch); } $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($curlError !== '' || $statusCode == 0) { $statusCode = 500; } $response = new RestfulService_Response($responseBody, $statusCode); curl_close($ch); return $response; }
/** * Fetches the JSON data from the Oembed URL (cached). * Only sets the internal variable. */ protected function loadData() { if ($this->data !== false) { return; } $timeout = 5; $sapphireInfo = new SapphireInfo(); $useragent = 'SilverStripe/' . $sapphireInfo->Version(); $curlRequest = curl_init(); curl_setopt_array($curlRequest, array(CURLOPT_URL => $this->url, CURLOPT_RETURNTRANSFER => 1, CURLOPT_USERAGENT => $useragent, CURLOPT_CONNECTTIMEOUT => $timeout, CURLOPT_FOLLOWLOCATION => 1)); $response = curl_exec($curlRequest); $headers = curl_getinfo($curlRequest); if (!$response || $headers['http_code'] !== 200) { $this->data = array(); return; } $body = $response; $data = json_decode($body, true); if (!$data) { // if the response is no valid JSON we might have received a binary stream to an image $data = array(); if (!function_exists('imagecreatefromstring')) { throw new LogicException('imagecreatefromstring function does not exist - Please make sure GD is installed'); } $image = imagecreatefromstring($body); if ($image !== FALSE) { preg_match("/^(http:\\/\\/)?([^\\/]+)/i", $this->url, $matches); $protocoll = $matches[1]; $host = $matches[2]; $data['type'] = "photo"; $data['title'] = basename($this->url) . " ({$host})"; $data['url'] = $this->url; $data['provider_url'] = $protocoll . $host; $data['width'] = imagesx($image); $data['height'] = imagesy($image); $data['info'] = _t('UploadField.HOTLINKINFO', 'Info: This image will be hotlinked. Please ensure you have permissions from the' . ' original site creator to do so.'); } } // Convert all keys to lowercase $data = array_change_key_case($data, CASE_LOWER); // Check if we can guess thumbnail if (empty($data['thumbnail_url']) && ($thumbnail = $this->findThumbnail($data))) { $data['thumbnail_url'] = $thumbnail; } // Purge everything if the type does not match. if ($this->type && $this->type != $data['type']) { $data = array(); } $this->data = $data; }
/** * Return the title, description, keywords and language metatags. * * @todo Move <title> tag in separate getter for easier customization and more obvious usage * * @param boolean|string $includeTitle Show default <title>-tag, set to false for custom templating * @param boolean $includeTitle Show default <title>-tag, set to false for * custom templating * @return string The XHTML metatags */ public function MetaTags($includeTitle = true) { $tags = ""; if($includeTitle === true || $includeTitle == 'true') { $tags .= "<title>" . Convert::raw2xml(($this->MetaTitle) ? $this->MetaTitle : $this->Title) . "</title>\n"; } $version = new SapphireInfo(); $tags .= "<meta name=\"generator\" http-equiv=\"generator\" content=\"SilverStripe ". $version->Version() ." - http://www.silverstripe.com\" />\n"; $charset = ContentNegotiator::get_encoding(); $tags .= "<meta http-equiv=\"Content-type\" content=\"text/html; charset=$charset\" />\n"; if($this->MetaKeywords) { $tags .= "<meta name=\"keywords\" http-equiv=\"keywords\" content=\"" . Convert::raw2att($this->MetaKeywords) . "\" />\n"; } if($this->MetaDescription) { $tags .= "<meta name=\"description\" http-equiv=\"description\" content=\"" . Convert::raw2att($this->MetaDescription) . "\" />\n"; } if($this->ExtraMeta) { $tags .= $this->ExtraMeta . "\n"; } $tags .= "<meta http-equiv=\"Content-Language\" content=\"". Translatable::current_lang() ."\"/>\n"; // DEPRECATED 2.3: Use MetaTags $this->extend('updateMetaTags', $tags); $this->extend('MetaTags', $tags); return $tags; }