array('*'), 'exclude-url' => array(), 'refresh' => '86400'); /** * * @param GadgetContext $context * @param Gadget $gadget */ public function __construct(GadgetContext $context, Gadget &$gadget) { parent::__construct($context, $gadget); // if no rewrite params are set in the gadget but rewrite_by_default is on, use our default rules (rewrite all) if (! isset($gadget->gadgetSpec->rewrite) && Config::get('rewrite_by_default')) { $this->rewrite = $this->defaultRewrite; } else { $this->rewrite = $gadget->gadgetSpec->rewrite; } // the base url of the gadget is used for relative paths $this->baseUrl = substr($this->context->getUrl(), 0, strrpos($this->context->getUrl(), '/') + 1); } /** * Register our dom node observers * * @param GadgetRewriter $gadgetRewriter */ public function register(GadgetRewriter &$gadgetRewriter) { $gadgetRewriter->addObserver('img', $this, 'rewriteImage'); $gadgetRewriter->addObserver('style', $this, 'rewriteStyle'); $gadgetRewriter->addObserver('script', $this, 'rewriteScript'); $gadgetRewriter->addObserver('link', $this, 'rewriteStyleLink'); } /** * Produces the proxied version of a URL if it falls within the content-rewrite params and * will append a refresh param to the proxied url based on the expires param, and the gadget * url so that the proxy server knows to rewrite it's content or not * * @param string $url * @return string */ private function getProxyUrl($url) { if (strpos(strtolower($url), 'http://') === false && strpos(strtolower($url), 'https://') === false) { $url = $this->baseUrl . $url; } $url = Config::get('web_prefix') . '/gadgets/proxy?url=' . urlencode($url); $url .= '&refresh=' . (isset($this->rewrite['expires']) && is_numeric($this->rewrite['expires']) ? $this->rewrite['expires'] : '3600'); $url .= '&gadget=' . urlencode($this->context->getUrl()); $url .= '&st=' . urlencode(BasicSecurityToken::getTokenStringFromRequest()); return $url; } /** * Checks the URL against the include-url and exclude-url params * * @param string $url * @param boolean */ private function includedUrl($url) { $included = $excluded = false; if (isset($this->rewrite['include-url'])) { foreach ($this->rewrite['include-url'] as $includeUrl) { if ($includeUrl == '*' || $includeUrl == '.*' || strpos($url, $includeUrl) !== false) { $included = true; break; } } } if (isset($this->rewrite['exclude-url'])) { foreach ($this->rewrite['exclude-url'] as $excludeUrl) { if ($excludeUrl == '*' || $includeUrl == '.*' || strpos($url, $excludeUrl) !== false) { $excluded = true; break; } } } return ($included && ! $excluded); } /** * Rewrites the src attribute of an img tag * * @param DOMElement $node */ public function rewriteImage(\DOMElement &$node) { if (($src = $node->getAttribute('src')) != null && $this->includedUrl($src)) { $node->setAttribute('src', $this->getProxyUrl($src)); } } /** * Uses rewriteCSS to find url() constructs and rewrite them to their * proxied counterparts * * @param DOMElement $node */ public function rewriteStyle(\DOMElement &$node) { $node->nodeValue = $this->rewriteCSS($node->nodeValue); } /** * Does the actual CSS rewriting, this is a seperate function so it can be called * from the proxy handler too * * @param string $content * @return string */ public function rewriteCSS($content) { $newVal = ''; // loop through the url elements in the content while (($pos = strpos($content, 'url')) !== false) { // output everything before this url tag $newVal .= substr($content, 0, $pos + 3); $content = substr($content, $pos + 3); // low tech protection against miss-reading tags, if the open ( is to far away, this is probabbly a miss-read if (($beginTag = strpos($content, '(')) < 4) { $content = substr($content, $beginTag + 1); $endTag = strpos($content, ')'); $tag = str_replace(array("'", "\""), '', trim(substr($content, 0, $endTag))); // at this point $tag should be the actual url aka: http://example.org/bar/foo.gif if ($this->includedUrl($tag)) { $newVal .= "('" . $this->getProxyUrl($tag) . "')"; } else { $newVal .= "('$tag')"; } $content = substr($content, $endTag + 1); } } // append what's left $newVal .= $content; return $newVal; } /** * Rewrites