/** * Handles (RSS & Atom) Type.FEED parsing using Zend's feed parser * * @param RemoteContentRequest $result * @param string $url * @param int $numEntries * @param boolean $getSummaries * @return response string, either a json encoded feed structure or an error message */ private function parseFeed($result, $url, $numEntries = 3, $getSummaries = false) { require 'external/Zend/Feed.php'; $channel = array(); if ((int) $result->getHttpCode() == 200) { $content = $result->getResponseContent(); try { $feed = Zend_Feed::importString($content); if ($feed instanceof Zend_Feed_Rss) { // Try get author if ($feed->author()) { $author = $feed->author(); } else { if ($feed->creator()) { $author = $feed->creator(); } else { $author = null; } } // Loop over each channel item and store relevant data $counter = 0; $channel['Entry'] = array(); foreach ($feed as $item) { if ($counter >= $numEntries) { break; } $_entry = array(); $_entry['Title'] = $item->title(); $_entry['Link'] = $item->link(); if (!is_string($_entry['Link']) && isset($_entry['Link'][1]) && $_entry['Link'][1] instanceof DOMElement) { $_entry['Link'] = $_entry['Link'][1]->getAttribute('href'); } if ($getSummaries && $item->description()) { $_entry['Summary'] = $item->description(); } $date = 0; if ($item->date()) { $date = strtotime($item->date()); } else { if ($item->pubDate()) { $date = strtotime($item->pubDate()); } } $_entry['Date'] = $date; $channel['Entry'][] = $_entry; // Remember author if first found if (empty($author) && $item->author()) { $author = $item->author(); } else { if ($item->creator()) { $author = $item->creator(); } } $counter++; } $channel['Title'] = $feed->title(); $channel['URL'] = $url; $channel['Description'] = $feed->description(); if ($feed->link()) { if (is_array($feed->link())) { foreach ($feed->link() as $_link) { if ($_link->nodeValue) { $channel['Link'] = $_link->nodeValue; } } } else { $channel['Link'] = $feed->link(); } } if ($author != null) { $channel['Author'] = $author; } } elseif ($feed instanceof Zend_Feed_Atom) { // Try get author if ($feed->author()) { if ($feed->author->name()) { $author = $feed->author->name(); } else { if ($feed->author->email()) { $author = $feed->author->email(); } else { $author = $feed->author(); } } } else { $author = null; } // Loop over each entries and store relevant data $counter = 0; $channel['Entry'] = array(); foreach ($feed as $entry) { if ($counter >= $numEntries) { break; } $_entry = array(); $_entry['Title'] = $entry->title(); // get Link if rel="alternate" if ($entry->link('alternate')) { $_entry['Link'] = $entry->link('alternate'); } else { // if there's no alternate, pick the one without "rel" attribtue $_links = $entry->link; if (is_array($_links)) { foreach ($_links as $_link) { if (empty($_link['rel'])) { $_entry['Link'] = $_link['href']; break; } } } else { $_entry['Link'] = $_links['href']; } } if ($getSummaries && $entry->summary()) { $_entry['Summary'] = $entry->summary(); } $date = 0; if ($entry->updated()) { $date = strtotime($entry->updated()); } else { if ($entry->published()) { $date = strtotime($entry->published()); } } $_entry['Date'] = $date; $channel['Entry'][] = $_entry; // Remember author if first found if (empty($author) && $entry->author()) { if ($entry->author->name()) { $author = $entry->author->name(); } else { if ($entry->author->email()) { $author = $entry->author->email(); } else { $author = $entry->author(); } } } elseif (empty($author)) { $author = null; } $counter++; } $channel['Title'] = $feed->title(); $channel['URL'] = $url; $channel['Description'] = $feed->subtitle(); // get Link if rel="alternate" if ($feed->link('alternate')) { $channel['Link'] = $feed->link('alternate'); } else { // if there's no alternate, pick the one without "rel" attribtue $_links = $feed->link; if (is_array($_links)) { foreach ($_links as $_link) { if (empty($_link['rel'])) { $channel['Link'] = $_link['href']; break; } } } else { $channel['Link'] = $_links['href']; } } if (!empty($author)) { $channel['Author'] = $author; } } else { throw new Exception('Invalid feed type'); } $resp = json_encode($channel); } catch (Zend_Feed_Exception $e) { $resp = 'Error parsing feed: ' . $e->getMessage(); } } else { // feed import failed $resp = "Error fetching feed, response code: " . $result->getHttpCode(); } return $resp; }
private function setRequestCache(RemoteContentRequest $originalRequest, RemoteContentRequest $request, Cache $cache) { if ($request->isStrictNoCache()) { return; } $ignoreCache = $originalRequest->getOptions()->ignoreCache; if (($this->cachePostRequest || !$request->isPost()) && !$ignoreCache) { $ttl = Shindig_Config::get('cache_time'); if ((int) $request->getHttpCode() == 200) { // Got a 200 OK response, calculate the TTL to use for caching it if (($expires = $request->getResponseHeader('Expires')) != null) { // prefer to use the servers notion of the time since there could be a clock-skew, but otherwise use our own $date = $request->getResponseHeader('Date') != null ? $request->getResponseHeader('Date') : gmdate('D, d M Y H:i:s', $_SERVER['REQUEST_TIME']) . ' GMT'; // convert both dates to unix epoch seconds, and calculate the TTL date_default_timezone_set('GMT'); $date = strtotime($date); $expires = strtotime($expires); $ttl = $expires - $date; // Don't fall for the old expiration-date-in-the-past trick, we *really* want to cache stuff since a large SNS's traffic would devastate a gadget developer's server if ($expires - $date > 1) { $ttl = $expires - $date; } } // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html : The Cache-Control: max-age=<seconds> overrides the expires header, so if both are present this one will overwrite the $ttl if (($cacheControl = $request->getResponseHeader('Cache-Control')) != null) { $bits = explode('=', $cacheControl); foreach ($bits as $key => $val) { if ($val == 'max-age' && isset($bits[$key + 1])) { $ttl = $bits[$key + 1]; break; } } } } else { $ttl = 5 * 60; // cache errors for 5 minutes, takes the denial of service attack type behaviour out of having an error :) } $this->invalidateService->markResponse($request); $this->cache->set($originalRequest->toHash(), $request, $ttl); } }