Many services now use RSS feeds to distribute frequently updated information like news stories and status reports. Traffic Manager's powerful TrafficScript language lets you process RSS XML data, and this article describes how you can embed several RSS feeds into a web document.
It illustrates Traffic Manager's response rewriting capabilities, XML processing and its ability to query several external datasources while processing a web request.
In this example, we'll show how you can embed special RSS tags within a static web document. Traffic Manager will intercept these tags in the document and replace them with the appropriate RSS feed data:
We'll use a TrafficScript rule to process web responses, seek out the RSS tag and retrieve, format and insert the appropriate RSS data.
First, the TrafficScript rule needs to obtain the response data, and verify that the response is a simple HTML document. We don't want to process images or other document types!
# Check the response type $contentType = http.getResponseHeader( "Content-Type" ); if( ! string.startsWith( $contentType, "text/html" ) ) break; # Get the response data $body = http.getResponseBody();
Next, we can use a regular expression to search through the response data and find any RSS tags in it:
(.*?)<!RSS\s+(.*?)\s+!>(.*)
Stingray supports Perl compatible regular expressions (regexs). This regex will find the first RSS tag in the document, and will assign text to the internal variables $1, $2 and $3:
The following code searches for RSS tags:
while( string.regexmatch( $body, '(.*?)<!RSS\s+(.*?)\s*!>(.*)' )) { $start = $1; $url = $2; $end = $3; }
An asynchronous HTTP request is sufficient to retrieve the RSS XML data:
$rss = http.request.get( $url );
The following XSLT transform can be used to extract the first 4 RSS items and format them up as an HTML <UL> list:
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <ul> <xsl:apply-templates select="//item[position()<5]"/> </ul> </xsl:template> <xsl:template match="item"> <xsl: param name="URL" select="link/text()"/> <xsl: param name="TITLE" select="title/text()"/> <li><a href="{$URL}"><xsl:value-of select="$TITLE"/></a></li> </xsl:template> </xsl:stylesheet>
Store the XSLT file in the Traffic Manager conf/extra directory, naming it 'rss.xslt', so that the rule can look it up using resource.get().
You can apply the XSLT transform to the XML data using the xml.xslt.transform function. The function returns the result with HTML entity encoding; use string.htmldecode to remove these:
$xsl = resource.get( "rss.xslt" ); $html= string.htmldecode( xml.xslt.transform( $rss, $xsl ) );
The entire response rule, with a little additional error checking, looks like this:
$contentType = http.getResponseHeader( "Content-Type" ); if( ! string.startsWith( $contentType, "text/html" ) ) break;
$body = http.getResponseBody(); $new = ""; $changed = 0;
while( string.regexmatch( $body, '(.*?)<!RSS\s+(.*?)\s*!>(.*)' )) { $start = $1; $url = $2; $end = $3; $html = "<ul><li><b>RSS: ".$url."</b></li></ul>"; $rss = http.request.get( $url ); if( $1 != 200 ) { $html = "<ul><li><b>Failed to retreive RSS feed</b></li></ul>"; } else { $xsl = resource.get( "rss.xslt" ); $html = string.htmldecode( xml.xslt.transform( $rss, $xsl ) ); if( $html == -1 ) { $html = "<ul><li><b>Failed to parse RSS feed</b></li></ul>"; } } $new = $new . $start . $html; $body = $end; $changed = 1; } if( $changed ) http.setresponsebody( $new . $body );