<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Abhi&#039;s Weblog</title>
	<atom:link href="http://abhinavsingh.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://abhinavsingh.com/blog</link>
	<description>PHP, Memcached, XMPP and Web Development</description>
	<lastBuildDate>Wed, 24 Feb 2010 09:35:05 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Wordpress Toolbar v 2.2 : Custom toolbar url,  Support for WPMU and bug fixes</title>
		<link>http://abhinavsingh.com/blog/2010/02/wordpress-toolbar-v-2-2-custom-toolbar-url-support-for-wpmu-and-bug-fixes/</link>
		<comments>http://abhinavsingh.com/blog/2010/02/wordpress-toolbar-v-2-2-custom-toolbar-url-support-for-wpmu-and-bug-fixes/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 17:26:04 +0000</pubDate>
		<dc:creator>Abhinav Singh</dc:creator>
				<category><![CDATA[Open Source Projects]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Toolbar]]></category>

		<guid isPermaLink="false">http://abhinavsingh.com/blog/?p=583</guid>
		<description><![CDATA[


Wordpress toolbar plugin provide a facebook, digg style toolbar for all outgoing links from your blog posts. The toolbar url defaults to http://yourblog/wp-content/plugins/wordpress-toolbar/toolbar.php. However with version 2.2, blog admin can customize toolbar url to http://yourblog/wordpress-toolbar/ through the admin panel. A lot of other enhancements have been added like cross-plugin compatibility and support for WPMU hosted [...]]]></description>
			<content:encoded><![CDATA[<div style="float:right;border:4px solid #464646;padding:5px;width:110px;height:105px;margin-left:10px;position:relative;">
<a href="http://downloads.wordpress.org/plugin/wordpress-toolbar.2.2.6.zip"><img style="border:0px;" src="http://abhinavsingh.com/blog/wp-content/uploads/2009/02/download-plugin.jpg" alt="download-wordpress-plugin" title="download-wordpress-plugin" width="108" height="108" class="size-full wp-image-280" /></a>
</div>
<p>Wordpress toolbar plugin provide a facebook, digg style toolbar for all outgoing links from your blog posts. The toolbar url defaults to <code>http://yourblog/wp-content/plugins/wordpress-toolbar/toolbar.php</code>. However with version 2.2, blog admin can customize toolbar url to <code>http://yourblog/wordpress-toolbar/</code> through the admin panel. A lot of other enhancements have been added like cross-plugin compatibility and support for WPMU hosted blogs. Check full feature list below.</p>
<p><strong style="font-size:18px;"><u>What&#8217;s New?</u></strong><br />
Listed below is list of new features and bug fixes released with v 2.2:</p>
<ol>
<li>Support for customizing toolbar url through admin panel</li>
<li>Support for WPMU hosted blogs</li>
<li>Support for removing &#8220;Get this Plugin&#8221; widget from the toolbar through admin panel</li>
<li>Security fix for possible XSS attack. Fix done by passing encoded hash string instead of plain text parameters. Also added various security checks on toolbar page to avoid possible XSS attacks.</li>
<li>Bug fix where plugin didn&#8217;t work as expected because of cross plugin compatibility issues. Fix done by replacing server side toolbar logic with client side (using jquery) logic.</li>
<li>Bug fix to show sociable share icons and tinyurl share link only for single posts and pages</li>
<li>Bug fix for unrecognizable code in the toolbar when the encoding of hosted blog is different from utf-8. Fix done by using hosted blog settings instead of hardcoded utf-8.</li>
</ol>
<p>Also core plugin code has been restructured (OOPS oriented now) so that maintainability and support becomes easier and quicker.</p>
<p><strong style="font-size:18px;"><u>Steps to customize the default toolbar URL</u></strong><br />
Enable Wordpress Toolbar v 2.2 plugin. Assuming you want to change default toolbar url from <code>/wp-content/plugins/wordpress-toolbar/toolbar.php</code> to <code>/wordpress-toolbar</code>, follow these steps:</p>
<ol>
<li>Enable apache <code>mod_rewrite</code></li>
<li>Add <code>AllowOverride All</code> in your blog virtual host config file and restart apache</li>
<li>Add following apache rewrite rule by editing your blog <code>.htaccess</code> file
<pre class="php" name="code">RewriteRule ^wordpress-toolbar$ wp-content/plugins/wordpress-toolbar/toolbar.php
RewriteRule ^wordpress-toolbar/$ wp-content/plugins/wordpress-toolbar/toolbar.php</pre>
</li>
<li>If you have blogs hosted using <strong>WPMU</strong>, add following apache rewrite rules in <code>.htaccess</code> file
<pre class="php" name="code">RewriteRule ^wordpress-toolbar$ wp-content/plugins/wordpress-toolbar/toolbar.php
RewriteRule ^wordpress-toolbar/$ wp-content/plugins/wordpress-toolbar/toolbar.php
RewriteRule ^([0-9a-zA-Z-]+)/wordpress-toolbar$ $1/wp-content/plugins/wordpress-toolbar/toolbar.php
RewriteRule ^([0-9a-zA-Z-]+)/wordpress-toolbar/$ $1/wp-content/plugins/wordpress-toolbar/toolbar.php</pre>
</li>
<li>Manually check if rewrite rules are working. Open your custom toolbar url and you should see a result similar to this <a href="http://abhinavsingh.com/blog/wordpress-toolbar">http://abhinavsingh.com/blog/wordpress-toolbar</a></li>
<li>If for some reasons you DO NOT see <strong>&#8220;Working! Though required parameters are missing.&#8221;</strong> on toolbar page, it means rewrite rules didn&#8217;t worked as expected. Before you proceed with the setup, you SHOULD fix rewrite rules</li>
<li>Go to wordpress admin and click <code>"Wordpress Toolbar"</code> under Settings tab</li>
<li>Update your new custom toolbar url as shown: <img src="http://abhinavsingh.com/blog/wp-content/uploads/2010/02/wordpress-toolbar-v-2.2-custom-toolbar-url-demo.png" alt="wordpress-toolbar-v-2.2-custom-toolbar-url-demo" title="wordpress-toolbar-v-2.2-custom-toolbar-url-demo" width="733" height="160" class="aligncenter size-full wp-image-584"/></li>
<li>Clear cache and verify your toolbar</li>
</ol>
<p>Enjoy and kindly let me know if you have issues installing plugin on your host. </p>
<script type="text/javascript">var wordpress_toolbar_urls = ["http:\/\/downloads.wordpress.org\/plugin\/wordpress-toolbar.2.2.6.zip"];var wordpress_toolbar_url = "http://abhinavsingh.com/blog/wordpress-toolbar";var wordpress_toolbar_oinw = "oinw";var wordpress_toolbar_hash = "aHR0cDovL2FiaGluYXZzaW5naC5jb20vYmxvZy8yMDEwLzAyL3dvcmRwcmVzcy10b29sYmFyLXYtMi0yLWN1c3RvbS10b29sYmFyLXVybC1zdXBwb3J0LWZvci13cG11LWFuZC1idWctZml4ZXMvPHdwdGI%2BV29yZHByZXNzIFRvb2xiYXIgdiAyLjIgOiBDdXN0b20gdG9vbGJhciB1cmwsICBTdXBwb3J0IGZvciBXUE1VIGFuZCBidWcgZml4ZXM8d3B0Yj5odHRwOi8vYWJoaW5hdnNpbmdoLmNvbS9ibG9nPHdwdGI%2BQWJoaSYjMDM5O3MgV2VibG9n";</script>]]></content:encoded>
			<wfw:commentRss>http://abhinavsingh.com/blog/2010/02/wordpress-toolbar-v-2-2-custom-toolbar-url-support-for-wpmu-and-bug-fixes/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Writing your first facebook chat bot in PHP using Jaxl library</title>
		<link>http://abhinavsingh.com/blog/2010/02/writing-your-first-facebook-chat-bot-in-php-using-jaxl-library/</link>
		<comments>http://abhinavsingh.com/blog/2010/02/writing-your-first-facebook-chat-bot-in-php-using-jaxl-library/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 22:18:32 +0000</pubDate>
		<dc:creator>Abhinav Singh</dc:creator>
				<category><![CDATA[XMPP]]></category>
		<category><![CDATA[Bots]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[JAXL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://abhinavsingh.com/blog/?p=582</guid>
		<description><![CDATA[Today facebook officially announced availability of it&#8217;s chat through jabber/xmpp clients. This is a big win for XMPP, with almost 400 million new probable users adding into XMPP club. In this post, I will demonstrate how to connect to facebook chat servers using Jaxl client library in PHP. It can further be used to make [...]]]></description>
			<content:encoded><![CDATA[<p>Today facebook officially <a href="http://blog.facebook.com/blog.php?post=297991732130">announced</a> availability of it&#8217;s chat through jabber/xmpp clients. This is a big win for XMPP, with almost 400 million new probable users adding into XMPP club. In this post, I will demonstrate how to connect to facebook chat servers using Jaxl client library in PHP. It can further be used to make custom chat bots for facebook.</p>
<p><strong style="font-size:18px;"><u>Creating your first facebook chat bot:</u></strong><br />
Follow the steps to successfully run a facebook chat bot:</p>
<ol>
<li>Download <a href="http://jaxl.googlecode.com/files/jaxl-1.0.4.rar">Jaxl v 1.0.4</a> or checkout latest from trunk
<pre class="php" name="code">svn checkout http://jaxl.googlecode.com/svn/trunk/ jaxl-read-only</pre>
</li>
<li>Edit the configuration file config.ini.php as follows:
<pre class="php" name="code">  // Set an enviornment
  $env = "prod";

  $key = array("prod"=>array("user"=>"facebook_username",
                             "pass"=>"facebook_password",
                             "host"=>"chat.facebook.com",
                             "port"=>5222,
                             "domain"=>"chat.facebook.com"
                            ),</pre>
</li>
<li>Run from command line:
<pre class="php" name="code">abhinavsingh@abhinavsingh-desktop:/jaxl$ sudo php index.php
OSType: Linux, Registering shutdown for SIGINT and SIGTERM
OpenSSL: Enabled for CLI
Attempting DIGEST-MD5 Authentication...
Starting Session...
Requesting Feature List...
Requesting Roster List...
Setting Status...
Done
</pre>
</li>
</ol>
<p>Try to send a message to your running chat bot and you shall receive a default message back from the bot saying <em>&#8220;Hi, Thanks for your message&#8221;</em>.</p>
<p>See further sample codes and explaination on how to build a full fledged gaming chat bots under <a href="http://abhinavsingh.com/blog/category/xmpp/">xmpp category</a>.</p>
<script type="text/javascript">var wordpress_toolbar_urls = ["http:\/\/blog.facebook.com\/blog.php?post=297991732130","http:\/\/jaxl.googlecode.com\/files\/jaxl-1.0.4.rar"];var wordpress_toolbar_url = "http://abhinavsingh.com/blog/wordpress-toolbar";var wordpress_toolbar_oinw = "oinw";var wordpress_toolbar_hash = "aHR0cDovL2FiaGluYXZzaW5naC5jb20vYmxvZy8yMDEwLzAyL3dyaXRpbmcteW91ci1maXJzdC1mYWNlYm9vay1jaGF0LWJvdC1pbi1waHAtdXNpbmctamF4bC1saWJyYXJ5Lzx3cHRiPldyaXRpbmcgeW91ciBmaXJzdCBmYWNlYm9vayBjaGF0IGJvdCBpbiBQSFAgdXNpbmcgSmF4bCBsaWJyYXJ5PHdwdGI%2BaHR0cDovL2FiaGluYXZzaW5naC5jb20vYmxvZzx3cHRiPkFiaGkmIzAzOTtzIFdlYmxvZw%3D%3D";</script>]]></content:encoded>
			<wfw:commentRss>http://abhinavsingh.com/blog/2010/02/writing-your-first-facebook-chat-bot-in-php-using-jaxl-library/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>MEMQ : Fast queue implementation using Memcached and PHP only</title>
		<link>http://abhinavsingh.com/blog/2010/02/memq-fast-queue-implementation-using-memcached-and-php-only/</link>
		<comments>http://abhinavsingh.com/blog/2010/02/memq-fast-queue-implementation-using-memcached-and-php-only/#comments</comments>
		<pubDate>Sun, 07 Feb 2010 14:16:27 +0000</pubDate>
		<dc:creator>Abhinav Singh</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Memcache]]></category>
		<category><![CDATA[Queue]]></category>

		<guid isPermaLink="false">http://abhinavsingh.com/blog/?p=580</guid>
		<description><![CDATA[Memcached is a scalable caching solution developed by Danga interactive. One can do a lot of cool things using memcached including spam control, online-offline detection of users, building scalable web services. In this post, I will demonstrate and explain how to implement fast scalable queues in PHP.
MEMQ: Overview
Every queue is uniquely identified by it&#8217;s name. [...]]]></description>
			<content:encoded><![CDATA[<p>Memcached is a scalable caching solution developed by <a href="http://www.danga.com/">Danga interactive</a>. One can do a lot of <a href="http://abhinavsingh.com/blog/2009/01/memcached-and-n-things-you-can-do-with-it/">cool things using memcached</a> including spam control, online-offline detection of users, building scalable web services. In this post, I will demonstrate and explain how to implement fast scalable queues in PHP.</p>
<p><strong style="font-size:18px;"><u>MEMQ: Overview</u></strong><br />
Every queue is uniquely identified by it&#8217;s name. Let&#8217;s consider a queue named &#8220;foo&#8221; and see how MEMQ will implement it inside memcached:</p>
<ul>
<li>Two keys namely, <code>foo_head</code> and <code>foo_tail</code> contains meta information about the queue</li>
<li>While queuing, item is saved in key <code>foo_1234</code>, where 1234 is the current value of key foo_tail</li>
<li>While de-queuing, item saved in key <code>foo_123</code> is returned, where 123 is the current value of key foo_head</li>
<li>Value of keys <code>foo_head</code> and <code>foo_tail</code> start with 1 and gets incremented on every pop and push operation respectively</li>
<li>Value of key foo_head NEVER exceeds value of foo_tail. When value of two meta keys is same, queue is considered empty.</li>
</ul>
<p><strong style="font-size:18px;"><u>MEMQ: Code</u></strong><br />
<a href="http://abhinavsingh.googlecode.com/files/memq.class%282%29.php">Download</a> the PHP class implementation for MEMQ:</p>
<pre name="code" class="php">&lt;?php

	define('MEMQ_POOL', 'localhost:11211');
	define('MEMQ_TTL', 0);

	class MEMQ {

		private static $mem = NULL;

		private function __construct() {}

		private function __clone() {}

		private static function getInstance() {
			if(!self::$mem) self::init();
			return self::$mem;
		}

		private static function init() {
			$mem = new Memcached;
			$servers = explode(",", MEMQ_POOL);
			foreach($servers as $server) {
				list($host, $port) = explode(":", $server);
				$mem-&gt;addServer($host, $port);
			}
			self::$mem = $mem;
		}

		public static function is_empty($queue) {
			$mem = self::getInstance();
			$head = $mem-&gt;get($queue."_head");
			$tail = $mem-&gt;get($queue."_tail");

			if($head &gt;= $tail || $head === FALSE || $tail === FALSE)
				return TRUE;
			else
				return FALSE;
		}

		public static function dequeue($queue, $after_id=FALSE, $till_id=FALSE) {
			$mem = self::getInstance();

			if($after_id === FALSE &#038;&#038; $till_id === FALSE) {
				$tail = $mem-&gt;get($queue."_tail");
				if(($id = $mem-&gt;increment($queue."_head")) === FALSE)
					return FALSE;

				if($id &lt;= $tail) {
					return $mem-&gt;get($queue."_".($id-1));
				}
				else {
					$mem-&gt;decrement($queue."_head");
					return FALSE;
				}
			}
			else if($after_id !== FALSE &#038;&#038; $till_id === FALSE) {
				$till_id = $mem-&gt;get($queue."_tail");
			}

			$item_keys = array();
			for($i=$after_id+1; $i&lt;=$till_id; $i++)
				$item_keys[] = $queue."_".$i;
			$null = NULL;

			return $mem-&gt;getMulti($item_keys, $null, Memcached::GET_PRESERVE_ORDER);
		}

		public static function enqueue($queue, $item) {
			$mem = self::getInstance();

			$id = $mem-&gt;increment($queue."_tail");
			if($id === FALSE) {
				if($mem-&gt;add($queue."_tail", 1, MEMQ_TTL) === FALSE) {
					$id = $mem-&gt;increment($queue."_tail");
					if($id === FALSE)
						return FALSE;
				}
				else {
					$id = 1;
					$mem-&gt;add($queue."_head", $id, MEMQ_TTL);
				}
			}

			if($mem-&gt;add($queue."_".$id, $item, MEMQ_TTL) === FALSE)
				return FALSE;

			return $id;
		}

	}

?&gt;</pre>
<p><strong style="font-size:18px;"><u>MEMQ: Usage</u></strong><br />
The class file provide 3 methods which can be utilized for implementing queues:</p>
<ol>
<li><u>MEMQ::is_empty</u> &#8211; Returns TRUE if a queue is empty, otherwise FALSE</li>
<li><u>MEMQ::enqueue</u> &#8211; Queue up the passed item</li>
<li><u>MEMQ::dequeue</u> &#8211; De-queue an item from the queue</li>
</ol>
<p>Specifically MEMQ::dequeue can run in two modes depending upon the parameters passed, as defined below:</p>
<ol>
<li><u>$queue:</u> This is MUST for dequeue to work. If other optional parameters are not passed, top item from the queue is returned back</li>
<li><u>$after_id:</u> If this parameter is also passed along, all items from $after_id till the end of the queue are returned</li>
<li><u>$till_id:</u> If this paramater is also passed along with $after_id, dequeue acts like a popRange function</li>
</ol>
<p>Whenever optional parameters are passed, MEMQ do not remove the returned items from the queue.</p>
<p><strong style="font-size:18px;"><u>MEMQ: Is it working?</u></strong><br />
Add following line of code at the end of the above class file and hit the class file from your browser. You will get back inserted item id as response on the browser:</p>
<pre class="php" name="code">var_dump(MEMQ::enqueue($_GET['q'], time()));</pre>
<p>Lets see how cache keys looks like in memcached:</p>
<pre class="php" name="code">abhinavsingh@abhinavsingh-desktop:~$ telnet localhost 11211
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

get foo_head
VALUE foo_head 1 1
1
END

get foo_tail
VALUE foo_tail 1 1
2
END

get foo_1
VALUE foo_1 1 10
1265540583
END

get foo_2
VALUE foo_2 1 10
1265540585
END
</pre>
<p><strong style="font-size:18px;"><u>MEMQ: Benchmark</u></strong><br />
Below are the benchmarking results for varying load:</p>
<ol>
<li><u>Queuing performance:</u> 697.18 req/sec  (n=1000, c=100) and 258.64 req/sec (n=5000, c=500)</li>
<li><u>Dequeue performance:</u> 641.27 req/sec (n=1000, c=100) and 242.87 req/sec (n=5000, c=500)</li>
</ol>
<p><strong style="font-size:18px;"><u>MEMQ: Why and other alternatives</u></strong><br />
There are several open source alternatives which provide a lot more scalability. However, MEMQ was written because my application doesn&#8217;t expect a load in order of 10,000 hits/sec. Listed below are a few open source alternatives for applications expecting high load:</p>
<ol>
<li><u><a href="http://activemq.apache.org/">ActiveMQ</a>:</u> A reliable and fast solution under apache foundation</li>
<li><u><a href="http://www.rabbitmq.com/">RabbitMQ</a>:</u> Another reliable solution based on AMQP solution</li>
<li><u><a href="http://memcachedb.org/memcacheq/">Memcacheq</a>:</u> A mash-up of two very stable stacks namely memcached and berkleyDB. However, it&#8217;s installation is a bit tricky.</li>
</ol>
<p><strong style="font-size:18px;"><u>MEMQ: Mantra and Customization</u></strong><br />
At the base MEMQ implementation can be visualized as follows:</p>
<p>There is a race between two keys in memcached (foo_head and foo_tail). Both are incremented on every dequeue and queue operation respectively. However, foo_tail is strong enough and never allows foo_head to exceed. When value of keys foo_tail and foo_head are equal, queue is considered empty.</p>
<p>The above code file still doesn&#8217;t include utility methods like <code>MEMQ::total_items</code> etc. However, writing such methods should be pretty easy depending upon your application needs. Also depending upon your application requirement, you should also take care of overflowing integer values.</p>
<script type="text/javascript">var wordpress_toolbar_urls = ["http:\/\/www.danga.com\/","http:\/\/abhinavsingh.googlecode.com\/files\/memq.class%282%29.php","http:\/\/activemq.apache.org\/","http:\/\/www.rabbitmq.com\/","http:\/\/memcachedb.org\/memcacheq\/"];var wordpress_toolbar_url = "http://abhinavsingh.com/blog/wordpress-toolbar";var wordpress_toolbar_oinw = "oinw";var wordpress_toolbar_hash = "aHR0cDovL2FiaGluYXZzaW5naC5jb20vYmxvZy8yMDEwLzAyL21lbXEtZmFzdC1xdWV1ZS1pbXBsZW1lbnRhdGlvbi11c2luZy1tZW1jYWNoZWQtYW5kLXBocC1vbmx5Lzx3cHRiPk1FTVEgOiBGYXN0IHF1ZXVlIGltcGxlbWVudGF0aW9uIHVzaW5nIE1lbWNhY2hlZCBhbmQgUEhQIG9ubHk8d3B0Yj5odHRwOi8vYWJoaW5hdnNpbmdoLmNvbS9ibG9nPHdwdGI%2BQWJoaSYjMDM5O3MgV2VibG9n";</script>]]></content:encoded>
			<wfw:commentRss>http://abhinavsingh.com/blog/2010/02/memq-fast-queue-implementation-using-memcached-and-php-only/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>JAXL BOSH Demo: IM chat client for all Wordpress blogs</title>
		<link>http://abhinavsingh.com/blog/2010/01/jaxl-bosh-demo-im-chat-client-for-all-wordpress-blogs/</link>
		<comments>http://abhinavsingh.com/blog/2010/01/jaxl-bosh-demo-im-chat-client-for-all-wordpress-blogs/#comments</comments>
		<pubDate>Thu, 28 Jan 2010 20:53:30 +0000</pubDate>
		<dc:creator>Abhinav Singh</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[XMPP]]></category>
		<category><![CDATA[Bosh]]></category>
		<category><![CDATA[Demo]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://abhinavsingh.com/blog/?p=576</guid>
		<description><![CDATA[Have you ever wished of a wordpress plugin capable of providing a facebook style chat bar on your blog post. In this blog post, I will lay down the details of how Jaxl&#8217;s bosh support comes in handy for building such browser based real time application. Specifically, I will explain how I achieved building a [...]]]></description>
			<content:encoded><![CDATA[<p>Have you ever wished of a wordpress plugin capable of providing a facebook style chat bar on your blog post. In this blog post, I will lay down the details of how <a href="http://code.google.com/p/jaxl">Jaxl</a>&#8217;s <a href="http://xmpp.org/extensions/xep-0206.html">bosh</a> support comes in handy for building such browser based real time application. Specifically, I will explain how I achieved building a plugin for my wordpress blog. If everything goes perfect over next few weeks, this plugin might be submitted in wordpress plugin&#8217;s directory.</p>
<p><strong style="font-size:18px;"><u>Jaxl BOSH Support Framework</u></strong><br />
Jaxl BOSH support comprise of three main parts:</p>
<ul>
<li><u>jaxl.jquery.js:</u> JQuery extension written for Jaxl bosh support</li>
<li><u>jaxl4bosh.class.php:</u> Connection manager in PHP</li>
<li><u>jaxl UI:</u> Integrated UI framework for changing your application skin on the fly. Your application skin can be a simple <a href="http://facebook.com">facebook</a> style chat bar (as on this page) or <a href="http://chesspark.com">chesspark</a> style whole html page</li>
</ul>
<p><code>jaxl.jquery.js</code> is responsible for initiating and maintaining a connection between the browser and the PHP connection manager. While <code>jaxl4bosh.class.php</code> implements the BOSH protocol and maintain a persistent connection with the jabber server.</p>
<p>jaxl.jquery.js provide a few basic methods like:</p>
<ul>
<li><u>jaxl.connect:</u> Call for initiating the connection</li>
<li><u>jaxl.sendMessage:</u> Call for sending a message to other jid&#8217;s</li>
<li><u>jaxl.ping:</u> Call to maintain the connection and gather any incoming data</li>
<li><u>jaxl.disconnect:</u> Call for disconnecting</li>
</ul>
<p>jaxl4bosh.class.php provide wordpress style filter/hooks which can be used to modify every incoming and outgoing messages.</p>
<ul>
<li><u>jaxl_pre_connect:</u> Call to perform initialization before jaxl connects to jabber server</li>
<li><u>jaxl_post_connect:</u> Call to perform shutdown after jaxl is connected to jabber server</li>
<li><u>jaxl_send_message:</u> Call to perform actions on outgoing messages from jaxl</li>
<li><u>jaxl_recv_message:</u> Call to perform actions on incoming messages to jaxl</li>
<li><u>jaxl_send_presence:</u> Call to perform actions on outgoing presence from jaxl</li>
<li><u>jaxl_recv_presence:</u> Call to perform actions on incoming presence from jaxl</li>
<li><u>jaxl_pre_disconnect:</u> Call to perform initialization before jaxl disconnects to jabber server</li>
<li><u>jaxl_post_disconnect:</u> Call to perform shutdown after jaxl is disconnected to jabber server</li>
</ul>
<p><strong style="font-size:18px;"><u>Jaxl and Wordpress</u></strong><br />
Using Jaxl bosh support require you to only edit the configuration file. Here are the config variables:</p>
<pre name="code" class="php">        // JAXL config
        define('JAXL_BOSH_HOST', 'localhost');
        define('JAXL_BOSH_SERVER', 'localhost');
        define('JAXL_BOSH_URL', 'http://localhost:7070/http-bind/');
        define('JAXL_ADMIN_JID', 'admin@localhost');
</pre>
<p>You can configure Jaxl to use any of the available <a href="http://xmpp.org/services/">public xmpp services</a>. However, I choose to host my own jabber server for my blog.</p>
<p><code>JAXL_ADMIN_JID</code> is the admin jid to which Jaxl should route all incoming messages, added specifically for wordpress related requirement. PHP connection manager can be extended to route different chat sessions to different admins.</p>
<p><code>jaxl_recv_message</code> handler is used to embed smiley&#8217;s and youtube videos by parsing the incoming chat messages.<br />
<img src="http://abhinavsingh.com/blog/wp-content/uploads/2010/01/jaxl-bosh-support-hook-demo-youtube-smiley.png" alt="jaxl-bosh-support-hook-demo-youtube-smiley" title="jaxl-bosh-support-hook-demo-youtube-smiley" width="413" height="407" class="aligncenter size-full wp-image-577" /></p>
<p>A few other hooks like <code>jaxl_post_connect</code> are used to notify <code>JAXL_ADMIN_JID</code> about the newly connected user.</p>
<p><strong style="font-size:18px;"><u>Admin Screen</u></strong><br />
Below is a screen shot of how an admin desktop will look like while chatting with his site visitors:<br />
<img src="http://abhinavsingh.com/blog/wp-content/uploads/2010/01/Admin-screenshot-jaxl-bosh-support.png" alt="Admin-screenshot-jaxl-bosh-support" title="Admin-screenshot-jaxl-bosh-support" width="413" height="602" class="aligncenter size-full wp-image-579" /></p>
<p>Let me know if you are having any issues chatting using the chat bar at the bottom of the page. Code and installation might be buggy at times, and would appreciate any help from you on it. </p>
<script type="text/javascript">var wordpress_toolbar_urls = ["http:\/\/code.google.com\/p\/jaxl","http:\/\/xmpp.org\/extensions\/xep-0206.html","http:\/\/facebook.com","http:\/\/chesspark.com","http:\/\/xmpp.org\/services\/"];var wordpress_toolbar_url = "http://abhinavsingh.com/blog/wordpress-toolbar";var wordpress_toolbar_oinw = "oinw";var wordpress_toolbar_hash = "aHR0cDovL2FiaGluYXZzaW5naC5jb20vYmxvZy8yMDEwLzAxL2pheGwtYm9zaC1kZW1vLWltLWNoYXQtY2xpZW50LWZvci1hbGwtd29yZHByZXNzLWJsb2dzLzx3cHRiPkpBWEwgQk9TSCBEZW1vOiBJTSBjaGF0IGNsaWVudCBmb3IgYWxsIFdvcmRwcmVzcyBibG9nczx3cHRiPmh0dHA6Ly9hYmhpbmF2c2luZ2guY29tL2Jsb2c8d3B0Yj5BYmhpJiMwMzk7cyBXZWJsb2c%3D";</script>]]></content:encoded>
			<wfw:commentRss>http://abhinavsingh.com/blog/2010/01/jaxl-bosh-demo-im-chat-client-for-all-wordpress-blogs/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Get real time system &amp; server load notification on any IM using PHP and XMPP</title>
		<link>http://abhinavsingh.com/blog/2010/01/get-real-time-system-server-load-notification-on-any-im-using-php-and-xmpp/</link>
		<comments>http://abhinavsingh.com/blog/2010/01/get-real-time-system-server-load-notification-on-any-im-using-php-and-xmpp/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 21:54:15 +0000</pubDate>
		<dc:creator>Abhinav Singh</dc:creator>
				<category><![CDATA[XMPP]]></category>
		<category><![CDATA[JAXL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://abhinavsingh.com/blog/?p=571</guid>
		<description><![CDATA[There are various system and server related information which server administrators always need to have as soon as possible, infact I must say in real time. There are several open and closed source softwares in the market which can generate almost real time notifications for you. Most famous one being Nagios. In this blog post [...]]]></description>
			<content:encoded><![CDATA[<p>There are various system and server related information which server administrators always need to have as soon as possible, infact I must say in real time. There are several open and closed source softwares in the market which can generate almost real time notifications for you. Most famous one being <a href="http://www.nagios.org/">Nagios</a>. In this blog post I will discuss, how to generate real time system notifications using PHP and <a href="http://xmpp.org">XMPP</a>. Specifically, I will present sample script using <a href="http://code.google.com/p/jaxl">Jaxl</a> (Jabber XMPP Client Library) for generating real time system load notifications, which can be received using any Instant Messengers.</p>
<p><strong style="font-size:18px;"><u>/proc/loadavg</u></strong><br />
We will be using system <code>/proc/loadavg</code> file to get real time system load information. If you are unaware about this file, here is in brief how this file is helpful to us:</p>
<pre class="php" name="code">sabhinav:~# cat /proc/loadavg
0.22 0.12 0.09 1/68 12621</pre>
<p>where first three columns measure the CPU and IO utilization of last one, five and 10 minute periods. The fourth column shows the number of currently running processes and the total number of processes. The last column displays the last process ID used.</p>
<p><strong style="font-size:18px;"><u>jaxl4serveradmins.class.php</u></strong><br />
We will be using Jaxl PHP client library for handling the XMPP part. <code>jaxl4serveradmins.class.php</code> is an extension to Jaxl, providing various server administration helper function. Below is the code for server administration extension:</p>
<pre class="php" name="code">  include_once("xmpp.class.php");

  define('JAXL_SERVER_ADMIN', 'mailsforabhinav@gmail.com');
  define('JAXL_SERVER_LOAD_POLL_INTERVAL', 10);

  class JAXL extends XMPP {

    function eventMessage($fromJid, $content, $offline = FALSE) {
    }

    function eventPresence($fromJid, $status, $photo) {
    }

    function eventNewEMail($total,$thread,$url,$participation,$messages,$date,$senders,$labels,$subject,$snippet) {
      // Not used here. See jaxl4gmail.class.php for it's use case
    }

    function setStatus() {
      // Set a custom status or use $this->status
      $this->sendStatus($this->status);
      print "Setting Status...\n";
      print "Done\n";

      $this->addJob(JAXL_SERVER_LOAD_POLL_INTERVAL, array($this, 'parseServerLoad'));
    }

    function parseServerLoad() {
      $loadavg = file_get_contents('/proc/loadavg');
      $this->sendMessage(JAXL_SERVER_ADMIN, $loadavg);
    }

  }</pre>
<p>I have utilized <code>addJob()</code> method provided by Jaxl library, using which you can specify a callback to be called after every N seconds (in short a periodic cron). Here we add a periodic job to be runned every JAXL_SERVER_LOAD_POLL_INTERVAL seconds. <code>parseServerLoad()</code> method is called as the callback function.</p>
<pre class="php" name="code">$this->addJob(JAXL_SERVER_LOAD_POLL_INTERVAL, array($this, 'parseServerLoad'));</pre>
<p>To keep the demo simple, I am simply sending the content of <code>/proc/loadavg</code> file as a message to server admins.</p>
<pre class="php" name="code">    function parseServerLoad() {
      $loadavg = file_get_contents('/proc/loadavg');
      $this->sendMessage(JAXL_SERVER_ADMIN, $loadavg);
    }</pre>
<p><strong style="font-size:18px;"><u>Running it for your servers:</u></strong><br />
Follow the following steps to get this started on your server (only Unix, no Windows):</p>
<ul>
<li>Checkout from Jaxl trunk
<pre class="php" name="code">sabhinav:~# sudo svn checkout http://jaxl.googlecode.com/svn/trunk/ jaxl-read-only</pre>
</li>
<li>Enter checked out directory
<pre class="php" name="code">sabhinav:~# cd jaxl-read-only</pre>
</li>
<li>Enter your server admin IM contact details
<pre class="php" name="code">sabhinav:~# sudo vim config.ini.php
define('JAXL_SERVER_ADMIN', 'webmaster@foobar.com');</pre>
</li>
<li>Enable server administration extension
<pre class="php" name="code">sabhinav:~# sudo vim index.php
include_once("jaxl4serveradmins.class.php"); // include_once("jaxl.class.php");</pre>
</li>
<li>Wroom Wroom, start Jaxl
<pre class="php" name="code">sabhinav:~# sudo php index.php
Starting TLS Encryption...
Attempting PLAIN Authentication...
Starting Session...
Requesting Feature List...
Requesting Roster List...
Setting Status...
Done
</pre>
</li>
</ul>
<p>Tail the jaxl log file in case you are facing any difficulties in the setup.
<pre class="php" name="code">sabhinav:~# tail -f log/logger.log</pre>
<p> You should also consider adding <code>/proc/</code> directory under <code>open_basedir</code> in <code>php.ini</code> file.</p>
<p><strong style="font-size:18px;"><u>Is it working?</u></strong><br />
If all is well configured server admins will start getting notifications every 10 seconds which is default value for JAXL_SERVER_LOAD_POLL_INTERVAL.<br />
<img src="http://abhinavsingh.com/blog/wp-content/uploads/2010/01/Jaxl4serveradmins.class.php-example-screenshot-for-system-load.png" alt="Jaxl4serveradmins.class.php example screenshot for system load" title="Jaxl4serveradmins.class.php example screenshot for system load" width="510" height="142" class="aligncenter size-full wp-image-572" /></p>
<p><strong style="font-size:18px;"><u>Writing custom notifications</u></strong><br />
Above I demonstrate how we can use XMPP and PHP to generate real time system notification. However, you may want to modify <code>parseServerLoad()</code> method to send notifications only when the server load exceeds a certain value. You may also want to add other methods which can notify you of various System and Server level parameters in a similar fashion. Below are a few useful system administration commands:</p>
<pre class="php" name="code">sabhinav:~# free -m
sabhinav:~# vmstat 1 20</pre>
<p><strong style="font-size:18px;"><u>Is it really real time?</u></strong><br />
Since, <code>parseServerLoad()</code> method polls for <code>/proc/loadavg</code> file every 10 seconds, this is not exactly real time. However you can configure JAXL_SERVER_LOAD_POLL_INTERVAL to make it poll faster. You can also use <a href="http://abhinavsingh.com/blog/2009/11/writing-a-custom-unix-style-tail-in-php-using-libevent-api-on-mac-os-x-10-5-x-and-other-platforms/">libevent extension</a> in PHP to make it real time in real sense.</p>
<p>Do let me know if you write any interesting functionality, I will be more than happy to include it as a part of current extension.</p>
<script type="text/javascript">var wordpress_toolbar_urls = ["http:\/\/www.nagios.org\/","http:\/\/xmpp.org","http:\/\/code.google.com\/p\/jaxl"];var wordpress_toolbar_url = "http://abhinavsingh.com/blog/wordpress-toolbar";var wordpress_toolbar_oinw = "oinw";var wordpress_toolbar_hash = "aHR0cDovL2FiaGluYXZzaW5naC5jb20vYmxvZy8yMDEwLzAxL2dldC1yZWFsLXRpbWUtc3lzdGVtLXNlcnZlci1sb2FkLW5vdGlmaWNhdGlvbi1vbi1hbnktaW0tdXNpbmctcGhwLWFuZC14bXBwLzx3cHRiPkdldCByZWFsIHRpbWUgc3lzdGVtICYjMDM4OyBzZXJ2ZXIgbG9hZCBub3RpZmljYXRpb24gb24gYW55IElNIHVzaW5nIFBIUCBhbmQgWE1QUDx3cHRiPmh0dHA6Ly9hYmhpbmF2c2luZ2guY29tL2Jsb2c8d3B0Yj5BYmhpJiMwMzk7cyBXZWJsb2c%3D";</script>]]></content:encoded>
			<wfw:commentRss>http://abhinavsingh.com/blog/2010/01/get-real-time-system-server-load-notification-on-any-im-using-php-and-xmpp/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Get lyrics for any song using XMPP and PHP right into your IM &#8211; Add lyricsfly@gtalkbots.com</title>
		<link>http://abhinavsingh.com/blog/2010/01/get-lyrics-for-any-song-using-xmpp-and-php-right-into-your-im-add-lyricsflygtalkbots-com/</link>
		<comments>http://abhinavsingh.com/blog/2010/01/get-lyrics-for-any-song-using-xmpp-and-php-right-into-your-im-add-lyricsflygtalkbots-com/#comments</comments>
		<pubDate>Thu, 07 Jan 2010 17:03:39 +0000</pubDate>
		<dc:creator>Abhinav Singh</dc:creator>
				<category><![CDATA[XMPP]]></category>
		<category><![CDATA[Gtalkbots]]></category>
		<category><![CDATA[JAXL]]></category>
		<category><![CDATA[lyricsfly]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://abhinavsingh.com/blog/?p=568</guid>
		<description><![CDATA[XMPP is soon finding it&#8217;s way into real time applications other than just chat. I have combined JAXL (Jabber XMPP client library written in PHP) and the API from lyricsfly.com to build a real time chat bot which can assist you with lyrics for any song. You can start using it by simply adding lyricsfly@gtalkbots.com [...]]]></description>
			<content:encoded><![CDATA[<p>XMPP is soon finding it&#8217;s way into real time applications other than just chat. I have combined <a href="http://code.google.com/p/jaxl">JAXL</a> (Jabber XMPP client library written in PHP) and the API from <a href="http://lyricsfly.com">lyricsfly.com</a> to build a real time chat bot which can assist you with lyrics for any song. You can start using it by simply adding lyricsfly@gtalkbots.com to your IM account (e.g. Gtalk, Jabber etc). In this blog post, I will explain in brief the working of lyricsfly bot and how you can integrate XMPP into your own application.</p>
<p><strong style="font-size:18px;"><u>Try out lyricsfly@gtalkbots.com</u></strong><br />
Follow the following steps to get the bot working for you:</p>
<ul>
<li>Login to your gtalk account using any of the IM available</li>
<li>Press Add Contact</li>
<li>Add <code>lyricsfly@gtalkbots.com</code> as your chat buddy</li>
<li>Send a chat message in following format &#8220;Song Title &#8211; Song Artist&#8221; e.g. &#8220;one &#8211; metallica&#8221;</li>
<li>You should see something like this: <img src="http://abhinavsingh.com/blog/wp-content/uploads/2010/01/lyricsfly@gtalkbots.com-Demo-for-one-metallica.png" alt="lyricsfly@gtalkbots.com Demo for &quot;one-metallica&quot;" title="lyricsfly@gtalkbots.com Demo for &quot;one-metallica&quot;" width="550" height="409" class="aligncenter size-full wp-image-569" /></li>
</ul>
<p><strong style="font-size:18px;"><u>Working of lyricsfly@gtalkbots.com with Jaxl</u></strong><br />
Here is in brief the working of lyricsfly bot using Jaxl client library:</p>
<ul>
<li>When someone sends a message like &#8220;one &#8211; metallica&#8221;  to the bot, <code>eventMessage()</code> method is called inside <code>jaxl.class.php</code></li>
<li>eventMessage then extracts the song title and artist name from the message using PHP explode. Filter the title and artist names for allowed characters.</li>
<li>eventMessage also calls lyricsfly API and fetch the lyrics. Finally it sends the lyrics as message to requester.</li>
<li>eventMessage also uses memcached to cache the lyrics. It decreases both response time and load on lyricsfly servers</li>
<li>Bot also keeps a count of number of queries from a particular user. Since it is still under development, currently there is a limit on number of lyrics you can fetch in a single day.</li>
</ul>
<p><strong style="font-size:18px;"><u>Making your own custom bot</u></strong></p>
<ul>
<li>Checkout latest from the trunk
<pre class="php" name="code">sabhinav$ svn checkout http://jaxl.googlecode.com/svn/trunk/ jaxl-read-only</li>
<li>Edit config file with your bot username, password and jabber servers</li>
<li>Run from command like
<pre class="php" name="code">php index.php</pre>
</li>
<li>To customize the bot modify <code>eventMessage</code> and <code>eventPresence</code> methods of Jaxl class inside <code>jaxl.class.php</code></li>
</ul>
<p>For a full fledged running bot example code, edit index.php and include<a href="http://abhinavsingh.com/blog/2009/01/how-to-get-dzone-feeds-as-im-using-jaxl-add-dzonegtalkbotscom/"> jaxl4dzone.class.php</a> instead of jaxl.class.php and re-run the bot.</p>
<p>Have fun and enjoy singing songs along with the lyrics.</p>
<script type="text/javascript">var wordpress_toolbar_urls = ["http:\/\/code.google.com\/p\/jaxl","http:\/\/lyricsfly.com"];var wordpress_toolbar_url = "http://abhinavsingh.com/blog/wordpress-toolbar";var wordpress_toolbar_oinw = "oinw";var wordpress_toolbar_hash = "aHR0cDovL2FiaGluYXZzaW5naC5jb20vYmxvZy8yMDEwLzAxL2dldC1seXJpY3MtZm9yLWFueS1zb25nLXVzaW5nLXhtcHAtYW5kLXBocC1yaWdodC1pbnRvLXlvdXItaW0tYWRkLWx5cmljc2ZseWd0YWxrYm90cy1jb20vPHdwdGI%2BR2V0IGx5cmljcyBmb3IgYW55IHNvbmcgdXNpbmcgWE1QUCBhbmQgUEhQIHJpZ2h0IGludG8geW91ciBJTSAmIzgyMTE7IEFkZCBseXJpY3NmbHlAZ3RhbGtib3RzLmNvbTx3cHRiPmh0dHA6Ly9hYmhpbmF2c2luZ2guY29tL2Jsb2c8d3B0Yj5BYmhpJiMwMzk7cyBXZWJsb2c%3D";</script>]]></content:encoded>
			<wfw:commentRss>http://abhinavsingh.com/blog/2010/01/get-lyrics-for-any-song-using-xmpp-and-php-right-into-your-im-add-lyricsflygtalkbots-com/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Wordpress style &#8220;Duplicate comment detected&#8221; using Memcached and PHP</title>
		<link>http://abhinavsingh.com/blog/2010/01/wordpress-style-duplicate-comment-detected-using-memcached-and-php/</link>
		<comments>http://abhinavsingh.com/blog/2010/01/wordpress-style-duplicate-comment-detected-using-memcached-and-php/#comments</comments>
		<pubDate>Fri, 01 Jan 2010 19:00:04 +0000</pubDate>
		<dc:creator>Abhinav Singh</dc:creator>
				<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Memcache]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Spam]]></category>

		<guid isPermaLink="false">http://abhinavsingh.com/blog/?p=558</guid>
		<description><![CDATA[If you have a knack of leaving comments on blogs, chances are you might have experienced a wordpress error page saying &#8220;Duplicate comment detected; it looks as though you’ve already said that!&#8220;, probably because you were not sure that your comment was saved last time and you tried to re-post your comment. In this blog [...]]]></description>
			<content:encoded><![CDATA[<p>If you have a knack of leaving comments on blogs, chances are you might have experienced a wordpress error page saying &#8220;<em>Duplicate comment detected; it looks as though you’ve already said that!</em>&#8220;, probably because you were not sure that your comment was saved last time and you tried to re-post your comment. In this blog post, I will put up some sample PHP code for Duplicate comment detection using Memcached without touching the databases. Towards the end, I will also discuss how the script can be modified for usage in any environment including forums and social networking websites.</p>
<p><strong style="font-size:18px;"><u>Duplicate comment detection using Memcached</u></strong><br />
Here is a php function called <code>is_repetitive_comment</code> which return some useful value if the comment is repetitive, otherwise FALSE.</p>
<pre class="php" name="code">&lt;?php

        define('COMPRESSION', 0);
        define('SIGNATURE_TTL', 60);

        $mem = new Memcache;
        $mem->addServer("localhost", 11211);

        function is_repetitive_comment($comment, $username) { // username can be ip address for anonymous env
                                                              // for per blog/forum checks pass forum id too
                                                              // for multi-host using same memcached instance, pass hostname too
                                                              // for restricting post of same comment, don't pass username
                $comment = trim($comment);
                $signature = md5(implode('',func_get_args()));

                global $mem;
                if(($value = $mem->get($signature)) !== FALSE) {
                        error_log($signature." found at ".time());
                        return $value;
                }
                else {
                        $value = array('comment' => $comment,
                                       'by' => $username,
                                       /* Other information if you may want to save */
                                      );
                        $mem->set($signature, $value, COMPRESSION, SIGNATURE_TTL);
                        error_log($signature." set at ".time());
                        return FALSE;
                }
        }

?&gt;</pre>
<p><strong style="font-size:18px;"><u>Is it working?</u></strong><br />
Lets verify the working of the code and then we will dig into the code:</p>
<ul>
<li>Save the sample code in a file, name it index.php</li>
<li>Towards the end of the script add following 3 line of code:
<pre class="php" name="code">        var_dump(is_repetitive_comment("User Comment", "username"));
        sleep(5); // Simulating the case when a user might try to post the same comment again knowingly or unknowingly
                  // Similar kind of check is done in wordpress comment submission (though without memcached)
        var_dump(is_repetitive_comment("User Comment", "username"));</pre>
</li>
<li>Run from command line:
<pre class="php" name="code">sabhinav$ php index.php
6105b67d969642fe9e27bc052f29e259 set at 1262393877
bool(false)
6105b67d969642fe9e27bc052f29e259 found at 1262393882
array(2) {
  ["comment"]=>
  string(12) "User Comment"
  ["by"]=>
  string(8) "username"
}</pre>
</li>
<li>As seen, function <code>is_repetitive_comment</code> returns bool(false) for the first time. However, after 5 seconds when same comment is being submitted it throws back some useful information from previous submission.</li>
</ul>
<p><strong style="font-size:18px;"><u>Working of is_repetitive_comment</u></strong><br />
Here is in brief, how memcached is used for duplicate comment detection by the script:</p>
<ul>
<li>SIGNATURE_TTL defines the time limit between two similar comment submissions. Default set to 60 seconds</li>
<li><code>is_repetitive_comment</code> takes two parameter namely the comment itself and the username of the user trying to post the comment.</li>
<li>The function create a signature by combining the passed parameters and checks whether a <code>key=$signature</code> exists in memcache</li>
<li>If key is found, it means same user has posted the same comment in past SIGNATURE_TTL i.e. 60 seconds. Function simply return back the value set for the key from memcache</li>
<li>However, if key is NOT found, user is allowed to post the comment by returning FALSE. However function also sets a key=$signature into memcache</li>
</ul>
<p>The value of key=$signature depends upon your application and use case. You might want to save some useful parameters so that you can show appropriate error message without hitting the databases for anything.</p>
<p><strong style="font-size:18px;"><u>Extracting more from the sample script</u></strong><br />
Here is how you can modify the above sample script for various environments: </p>
<ul>
<li>If you are performing repetitive comment check in an anonymous environment i.e. commenter may not be registered users, you can pass commenter&#8217;s ip address instead of username</li>
<li>If you serve multiple sites out of the same box and all share the same memcached instance, you SHOULD also pass site&#8217;s root url to the function. Otherwise you might end up showing error message to wrong users</li>
<li>If you want to restrict submission of same comment per blog or forum, also pass the blog id to the function</li>
<li>If you want to simply restrict submission of same comment through out your site, pass only the comment to the function</li>
</ul>
<p>Let me know if you do similar tiny little hacks using memcached <img src='http://abhinavsingh.com/blog/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<script type="text/javascript">var wordpress_toolbar_urls = [];var wordpress_toolbar_url = "http://abhinavsingh.com/blog/wordpress-toolbar";var wordpress_toolbar_oinw = "oinw";var wordpress_toolbar_hash = "aHR0cDovL2FiaGluYXZzaW5naC5jb20vYmxvZy8yMDEwLzAxL3dvcmRwcmVzcy1zdHlsZS1kdXBsaWNhdGUtY29tbWVudC1kZXRlY3RlZC11c2luZy1tZW1jYWNoZWQtYW5kLXBocC88d3B0Yj5Xb3JkcHJlc3Mgc3R5bGUgJiM4MjIwO0R1cGxpY2F0ZSBjb21tZW50IGRldGVjdGVkJiM4MjIxOyB1c2luZyBNZW1jYWNoZWQgYW5kIFBIUDx3cHRiPmh0dHA6Ly9hYmhpbmF2c2luZ2guY29tL2Jsb2c8d3B0Yj5BYmhpJiMwMzk7cyBXZWJsb2c%3D";</script>]]></content:encoded>
			<wfw:commentRss>http://abhinavsingh.com/blog/2010/01/wordpress-style-duplicate-comment-detected-using-memcached-and-php/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>How to use locks in PHP cron jobs to avoid cron overlaps</title>
		<link>http://abhinavsingh.com/blog/2009/12/how-to-use-locks-in-php-cron-jobs-to-avoid-cron-overlaps/</link>
		<comments>http://abhinavsingh.com/blog/2009/12/how-to-use-locks-in-php-cron-jobs-to-avoid-cron-overlaps/#comments</comments>
		<pubDate>Mon, 28 Dec 2009 15:21:50 +0000</pubDate>
		<dc:creator>Abhinav Singh</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Cron Job]]></category>

		<guid isPermaLink="false">http://abhinavsingh.com/blog/?p=566</guid>
		<description><![CDATA[Cron jobs are hidden building blocks for most of the websites. They are generally used to process/aggregate data in the background. However as a website starts to grow and there is gigabytes of data to be processed by every cron job, chances are that our cron jobs might overlap and possibly corrupt our data. In [...]]]></description>
			<content:encoded><![CDATA[<p>Cron jobs are hidden building blocks for most of the websites. They are generally used to process/aggregate data in the background. However as a website starts to grow and there is gigabytes of data to be processed by every cron job, chances are that our cron jobs might overlap and possibly corrupt our data. In this blog post, I will demonstrate how can we avoid such overlaps by using simple locking techniques. I will also discuss a few edge cases we need to consider while using locks to avoid overlap.</p>
<p><strong style="font-size:18px;"><u>Cron job helper class</u></strong><br />
Here is a helper class (<code>cron.helper.php</code>) which will help us avoiding cron job overlaps. (See usage example below)</p>
<pre class="php" name="code">&lt;?php

	define('LOCK_DIR', '/Users/sabhinav/Workspace/cronHelper/');
	define('LOCK_SUFFIX', '.lock');

	class cronHelper {

		private static $pid;

		function __construct() {}

		function __clone() {}

		private static function isrunning() {
			$pids = explode(PHP_EOL, `ps -e | awk '{print $1}'`);
			if(in_array(self::$pid, $pids))
				return TRUE;
			return FALSE;
		}

		public static function lock() {
			global $argv;

			$lock_file = LOCK_DIR.$argv[0].LOCK_SUFFIX;

			if(file_exists($lock_file)) {
				//return FALSE;

				// Is running?
				self::$pid = file_get_contents($lock_file);
				if(self::isrunning()) {
					error_log("==".self::$pid."== Already in progress...");
					return FALSE;
				}
				else {
					error_log("==".self::$pid."== Previous job died abruptly...");
				}
			}

			self::$pid = getmypid();
			file_put_contents($lock_file, self::$pid);
			error_log("==".self::$pid."== Lock acquired, processing the job...");
			return self::$pid;
		}

		public static function unlock() {
			global $argv;

			$lock_file = LOCK_DIR.$argv[0].LOCK_SUFFIX;

			if(file_exists($lock_file))
				unlink($lock_file);

			error_log("==".self::$pid."== Releasing lock...");
			return TRUE;
		}

	}

?&gt;</pre>
<p><strong style="font-size:18px;"><u>Using cron.helper.php</u></strong><br />
Here is how the helper class can be integrated in your current cron job code:</p>
<ul>
<li>Save <code>cron.helper.php</code> in a folder called <code>cronHelper</code></li>
<li>Update LOCK_DIR as per your need</li>
<li>You might have to set proper permissions on folder cronHelper, so that running cron job have write permissions</li>
<li>Wrap your cron job code as show below:
<pre class="php" name="code">&lt;?php

	require 'cronHelper/cron.helper.php';

	if(($pid = cronHelper::lock()) !== FALSE) {

		/*
		 * Cron job code goes here
		*/
		sleep(10); // Cron job code for demonstration

		cronHelper::unlock();
	}

?&gt;</pre>
</li>
</ul>
<p><strong style="font-size:18px;"><u>Is it working? Verify</u></strong><br />
Lets verify is the helper class really take care of all the edge cases.</p>
<ul>
<li><code>sleep(10)</code> is our cron job code for this test</li>
<li>Run from command line:
<pre class="php" name="code">sabhinav$ php job.php
==40818== Lock acquired, processing the job...
==40818== Releasing lock...
</pre>
<p> where 40818 is the process id of current running cron job</li>
<li>Run from command line and terminate the cron job in between by pressing CNTR+C:
<pre class="php" name="code">sabhinav$ php job.php
==40830== Lock acquired, processing the job...
</pre>
<p> By pressing CNTR+C, we simulate the cases when a cron job can die in between due to a fatal error or system shutdown. In such cases, helper class fails to release the lock on this cron job.</li>
<li>With the lock in place (<code>ls -l cronHelper | grep lock</code>), run from command line:
<pre class="php" name="code">sabhinav$ php job.php
==40830== Previous job died abruptly...
==40835== Lock acquired, processing the job...
==40835== Releasing lock...
</pre>
<p> As seen, helper class detects that one of the previous cron job died abruptly and then allow the current job to run successfully.</li>
<li>Run the cron job from two command line window and one of them will not proceed as shown below:
<pre class="php" name="code">centurydaily-lm:cronHelper sabhinav$ php job.php
==40856== Already in progress...
</pre>
<p> One of the cron job will die since a cron job with <code>$pid=40856</code> is already in progress.</li>
</ul>
<p><strong style="font-size:18px;"><u>Working of cron.helper.php</u></strong><br />
The helper class create a lock file inside <code>LOCK_DIR</code>. For our test cron job above, lock file name will be <code>job.php.lock</code>. Lock file name suffix can be configured using <code>LOCK_SUFFIX</code>.</p>
<p><code>cronHelper::lock()</code> places the current running cron job process id inside the lock file. Upon job completion <code>cronHelper::unlock()</code> deletes the lock file.</p>
<p>If <code>cronHelper::lock()</code> finds that lock file already exists, it extracts the previous cron job process id from the lock file and checks whether a previous cron job is still running. If previous job is still in progress, we abort our current current job. If previous job is not in progress i.e. died abruptly, current cron job acquires the lock.</p>
<p>This is the classic method for avoiding cron overlaps. However there can be various other methods of achieving the same thing. If you know any do let me know through your comments.</p>
<script type="text/javascript">var wordpress_toolbar_urls = [];var wordpress_toolbar_url = "http://abhinavsingh.com/blog/wordpress-toolbar";var wordpress_toolbar_oinw = "oinw";var wordpress_toolbar_hash = "aHR0cDovL2FiaGluYXZzaW5naC5jb20vYmxvZy8yMDA5LzEyL2hvdy10by11c2UtbG9ja3MtaW4tcGhwLWNyb24tam9icy10by1hdm9pZC1jcm9uLW92ZXJsYXBzLzx3cHRiPkhvdyB0byB1c2UgbG9ja3MgaW4gUEhQIGNyb24gam9icyB0byBhdm9pZCBjcm9uIG92ZXJsYXBzPHdwdGI%2BaHR0cDovL2FiaGluYXZzaW5naC5jb20vYmxvZzx3cHRiPkFiaGkmIzAzOTtzIFdlYmxvZw%3D%3D";</script>]]></content:encoded>
			<wfw:commentRss>http://abhinavsingh.com/blog/2009/12/how-to-use-locks-in-php-cron-jobs-to-avoid-cron-overlaps/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>How to build a custom static file serving HTTP server using Libevent in C</title>
		<link>http://abhinavsingh.com/blog/2009/12/how-to-build-a-custom-static-file-serving-http-server-using-libevent-in-c/</link>
		<comments>http://abhinavsingh.com/blog/2009/12/how-to-build-a-custom-static-file-serving-http-server-using-libevent-in-c/#comments</comments>
		<pubDate>Sat, 12 Dec 2009 20:06:36 +0000</pubDate>
		<dc:creator>Abhinav Singh</dc:creator>
				<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Libevent]]></category>

		<guid isPermaLink="false">http://abhinavsingh.com/blog/?p=555</guid>
		<description><![CDATA[Libevent is an event notification library which lays the foundation for immensely successful open source projects like Memcached. As the web advances into a real time mode, more and more websites are using a mix of technologies like HTTP Pub-Sub, HTTP Long-polling and Comet with a custom light weight HTTP servers in the backend to [...]]]></description>
			<content:encoded><![CDATA[<p>Libevent is an event notification library which lays the foundation for immensely successful open source projects like Memcached. As the web advances into a real time mode, more and more websites are using a mix of technologies like HTTP Pub-Sub, HTTP Long-polling and Comet with a custom light weight HTTP servers in the backend to create a real time user experience. In this blog post, I will start with necessary prerequisites for setting up the development environment. Further, I will demonstrate how to build a HTTP server capable of serving static pages. Finally, I will put up a few use cases of a custom HTTP server in today&#8217;s world.</p>
<p><strong style="font-size:18px;"><u>Setting up Environment</u></strong><br />
Follow the following steps to install the latest version of libevent (version <a href="http://www.monkey.org/~provos/libevent/doxygen-2.0.1/">2.0.3-alpha</a>)</p>
<ul>
<li>$ wget http://www.monkey.org/~provos/libevent-2.0.3-alpha.tar.gz</li>
<li>$ tar -xvzf libevent-2.0.3-alpha.tar.gz</li>
<li>$ cd libevent-2.0.3-alpha.tar.gz</li>
<li>./configure</li>
<li>make</li>
<li>sudo make install</li>
</ul>
<p>Check the environment by running the following piece of C code (<code>event2.cpp</code>):</p>
<pre class="c" name="code">#include &lt;event2/event.h&gt;

int main(int argc, char **argv) {
	const char *version;
	version = event_get_version();
	printf("%s\n", version);
	return 0;
}</pre>
<p>Compile and run as following:</p>
<pre class="c" name="code">$ g++ -arch x86_64 -Wall -levent event2.cpp -o event2
$ ./event2
$ 2.0.3-alpha</pre>
<p>I had to pass <code>-arch x86_64</code> flags on Mac OSX 10.5.8. This can vary depending upon your operating system.</p>
<p><strong style="font-size:18px;"><u>Libsrvr: Static file serving HTTP Server</u></strong><br />
Below is the C code for a static file serving HTTP server using libevent called <strong>&#8220;Libsrvr&#8221;</strong>:</p>
<p><strong><u>libsrvr.h</u></strong></p>
<pre class="c" name="code">// General purpose header files
#include &lt;iostream&gt;
#include &lt;getopt.h&gt;
#include &lt;sys/stat.h&gt;

// Libevent header files
#include &lt;/usr/local/include/event2/event.h&gt;
#include &lt;/usr/local/include/event2/http.h&gt;
#include &lt;/usr/local/include/event2/buffer.h&gt;

// Libsrvr configuration settings
#define LIBSRVR_SIGNATURE "libsrvr v 0.0.1"
#define LIBSRVR_HTDOCS "/Users/sabhinav/libsrvr/www"
#define LIBSRVR_INDEX "/index.html"

// Libsrvr http server and base struct
struct evhttp *libsrvr;
struct event_base *libbase;

// Libsrvr options
struct _options {
	int port;
	char *address;
	int verbose;
} options;</pre>
<ul>
<li>LIBSRVR_SIGNATURE is the server signature sent as response header for all incoming requests</li>
<li>LIBSRVR_HTDOCS is the path to the the DocumentRoot for libsrvr</li>
<li>LIBSRVR_INDEX is the similar to DirectoryIndex directive of apache</li>
</ul>
<p><strong><u>libsrvr.cpp</u></strong></p>
<pre class="c" name="code">#include &lt;/Users/sabhinav/libsrvr/libsrvr.h&gt;

void router(struct evhttp_request *r, void *arg) {
	const char *uri = evhttp_request_get_uri(r);

	char *static_file = (char *) malloc(strlen(LIBSRVR_HTDOCS) + strlen(uri) + strlen(LIBSRVR_INDEX) + 1);
	stpcpy(stpcpy(static_file, LIBSRVR_HTDOCS), uri);

	bool file_exists = true;
	struct stat st;
	if(stat(static_file, &#038;st) == -1) {
		file_exists = false;
		evhttp_send_error(r, HTTP_NOTFOUND, "NOTFOUND");
	}
	else {
		if(S_ISDIR(st.st_mode)) {
			strcat(static_file, LIBSRVR_INDEX);

			if(stat(static_file, &#038;st) == -1) {
				file_exists = false;
				evhttp_send_error(r, HTTP_NOTFOUND, "NOTFOUND");
			}
		}
	}

	if(file_exists) {
		int file_size = st.st_size;

		char *html;
		html = (char *) alloca(file_size);

		if(file_size != 0) {
			FILE *fp = fopen(static_file, "r");
			fread(html, 1, file_size, fp);
			fclose(fp);
		}

		struct evbuffer *buffer;
		buffer = evbuffer_new();

		struct evkeyvalq *headers = evhttp_request_get_output_headers(r);
		evhttp_add_header(headers, "Content-Type", "text/html; charset=UTF-8");
		evhttp_add_header(headers, "Server", LIBSRVR_SIGNATURE);

		evbuffer_add_printf(buffer, "%s", html);
		evhttp_send_reply(r, HTTP_OK, "OK", buffer);
		evbuffer_free(buffer);

		if(options.verbose) fprintf(stderr, "%s\t%d\n", static_file, file_size);
	}
	else {
		if(options.verbose) fprintf(stderr, "%s\t%s\n", static_file, "404 Not Found");
	}

	free(static_file);
}

int main(int argc, char **argv) {
	int opt;

	options.port = 4080;
	options.address = "0.0.0.0";
	options.verbose = 0;

	while((opt = getopt(argc,argv,"p:vh")) != -1) {
		switch(opt) {
			case 'p':
				options.port = atoi(optarg);
				break;
			case 'v':
				options.verbose = 1;
				break;
			case 'h':
				printf("Usage: ./libsrvr -p port -v[erbose] -h[elp]\n");
				exit(1);
		}
	}

	libbase = event_base_new();
	libsrvr = evhttp_new(libbase);
	evhttp_bind_socket(libsrvr, options.address, options.port);
	evhttp_set_gencb(libsrvr, router, NULL);
	event_base_dispatch(libbase);

	return 0;
}</pre>
<p>Here is some explanation for the above code:</p>
<ul>
<li>Command line options are parsed using GNU <a href="http://www.gnu.org/s/libc/manual/html_node/Getopt.html">getopt</a> library</li>
<li><code>libbase</code> is the event base for HTTP server <code>libsrvr</code>.</li>
<li>HTTP server is bind to port 4080 (by default).</li>
<li>A callback function is registered for each incoming HTTP request to libsrvr. Function <code>router</code> is invoked every time a HTTP request is received</li>
<li>Finally <code>libbase</code> is dispatched and code never reaches <code>return 0</code></li>
</ul>
<p>The working of the <code>router</code> function is as follows:</p>
<ul>
<li>Incoming request uri is converted to absolute file path on the system</li>
<li>Checks for file or directory existence is done</li>
<li>If absolute path is a directory, LIBSRVR_INDEX is served out of that directory</li>
</ul>
<p><strong style="font-size:18px;"><u>Launching Libsrvr:</u></strong><br />
Compile and run the libsrvr as follows:</p>
<pre class="c" name="code">$ g++ -arch x86_64 -Wall -levent libsrvr.cpp -o libsrvr
$ ./libsrvr -v
/Users/sabhinav/libsrvr/www//index.html	538
/Users/sabhinav/libsrvr/www/assets/style.css	35
/Users/sabhinav/libsrvr/www/assets/script.js	27
/Users/sabhinav/libsrvr/www/dummy	404 Not Found
/Users/sabhinav/libsrvr/www/index.html	538
/Users/sabhinav/libsrvr/www/assets/style.css	35
</pre>
<p>If started under verbose mode (-v), libsrvr will output each requested file path on the console as shown above.</p>
<p><strong style="font-size:18px;"><u>Use cases</u></strong><br />
Below are a few use cases of a custom HTTP server as seen in web today:</p>
<ul>
<li><u>Facebook Chat</u>: Uses a custom http server based on <a href="http://code.google.com/p/mochiweb/">mochiweb</a> framework</li>
<li><u>Yahoo finance</u>: Uses a custom http streaming server based on libevent</li>
</ul>
<p>Generally, iframe technique is combined with javascript hacks for streaming data from the custom http servers. Read &#8220;<a href="http://abhinavsingh.com/blog/2009/11/making-cross-sub-domain-ajax-xhr-requests-using-mod_proxy-and-iframes/">How to make cross-sub-domain ajax (XHR) requests using mod_proxy and iframes</a>&#8221; for details.</p>
<p><strong style="font-size:18px;"><u>Conclusion</u></strong><br />
Though a static file server find little place in today&#8217;s world, the idea was to show the ease by which you can create your own HTTP server which is light weight, fast and scalable (all thanks to <a href="http://www.citi.umich.edu/u/provos/">Niels</a> for his libevent). Couple libsrvr with memcached for caching static files, and benchmark will show over <code>10,000 req/sec</code> handling capability of libsrvr.</p>
<p>Share if you like it and also let me know your thoughts through comments.</p>
<script type="text/javascript">var wordpress_toolbar_urls = ["http:\/\/www.monkey.org\/~provos\/libevent\/doxygen-2.0.1\/","http:\/\/www.gnu.org\/s\/libc\/manual\/html_node\/Getopt.html","http:\/\/code.google.com\/p\/mochiweb\/","http:\/\/www.citi.umich.edu\/u\/provos\/"];var wordpress_toolbar_url = "http://abhinavsingh.com/blog/wordpress-toolbar";var wordpress_toolbar_oinw = "oinw";var wordpress_toolbar_hash = "aHR0cDovL2FiaGluYXZzaW5naC5jb20vYmxvZy8yMDA5LzEyL2hvdy10by1idWlsZC1hLWN1c3RvbS1zdGF0aWMtZmlsZS1zZXJ2aW5nLWh0dHAtc2VydmVyLXVzaW5nLWxpYmV2ZW50LWluLWMvPHdwdGI%2BSG93IHRvIGJ1aWxkIGEgY3VzdG9tIHN0YXRpYyBmaWxlIHNlcnZpbmcgSFRUUCBzZXJ2ZXIgdXNpbmcgTGliZXZlbnQgaW4gQzx3cHRiPmh0dHA6Ly9hYmhpbmF2c2luZ2guY29tL2Jsb2c8d3B0Yj5BYmhpJiMwMzk7cyBXZWJsb2c%3D";</script>]]></content:encoded>
			<wfw:commentRss>http://abhinavsingh.com/blog/2009/12/how-to-build-a-custom-static-file-serving-http-server-using-libevent-in-c/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>How to add content verification using hmac in PHP</title>
		<link>http://abhinavsingh.com/blog/2009/12/how-to-add-content-verification-using-hmac-in-php/</link>
		<comments>http://abhinavsingh.com/blog/2009/12/how-to-add-content-verification-using-hmac-in-php/#comments</comments>
		<pubDate>Mon, 07 Dec 2009 13:53:46 +0000</pubDate>
		<dc:creator>Abhinav Singh</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[hmac]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://abhinavsingh.com/blog/?p=538</guid>
		<description><![CDATA[Many times a requirement arises where we are supposed to expose an API for intended users, who can use these API endpoints to GET/POST data on our servers. But how do we verify that only the intended users are using these API&#8217;s and not any hacker or attacker. In this blog post, I will show [...]]]></description>
			<content:encoded><![CDATA[<p>Many times a requirement arises where we are supposed to expose an API for intended users, who can use these API endpoints to GET/POST data on our servers. But how do we verify that only the intended users are using these API&#8217;s and not any hacker or attacker. In this blog post, I will show you the most elegant way of adding content verification using <a href="http://php.net/manual/en/function.hash-hmac.php">hash_hmac</a> (Hash-based Message Authentication Code) in PHP. This will allow us to restrict possible misuse of our API by simply issuing an API key for intended users.</p>
<p>Here are the steps for adding content verification using hmac in PHP:</p>
<ul>
<li>Issue <code>$private_key</code> and <code>$public_key</code> for users allowed to post data using our API. You can use the method similar to one <a href="http://abhinavsingh.com/blog/2009/08/how-to-generate-random-password-like-wordpress-using-php/">described here</a> for generating public and private keys.</li>
<li>Users having these keys can now use following sample script (<code>hmac-sender.php</code>) to submit data:
<pre class="php" name="code">        // User Public/Private Keys
        $private_key = 'private_key_user_id_9999';
        $public_key = 'public_key_user_id_9999';

        // Data to be submitted
        $data = 'This is a HMAC verification demonstration';

        // Generate content verification signature
        $sig = base64_encode(hash_hmac('sha1', $data, $private_key, TRUE));

        // Prepare json data to be submitted
        $json_data = json_encode(array('data'=>$data, 'sig'=>$sig, 'pubKey'=>$public_key));

        // Finally submit to api end point
        submit_to_api_end_point("http://yoursite.com/hmac-receiver.php?data=".urlencode($json_data));</pre>
</li>
<li>At <code>hmac-receiver.php</code>, we validate the incoming data in following fashion:
<pre class="php" name="code">        function get_private_key_for_public_key($public_key) {
                // extract private key from database or cache store
                return 'private_key_user_id_9999';
        }

        // Data submitted
        $data = $_GET['data'];
        $data = json_decode(stripslashes($data), TRUE);

        // User hit the end point API with $data, $signature and $public_key
        $message = $data['data'];
        $received_signature = $data['sig'];
        $private_key = get_private_key_for_public_key($data['pubKey']);
        $computed_signature = base64_encode(hash_hmac('sha1', $message, $private_key, TRUE));

        if($computed_signature == $received_signature) {
                echo "Content Signature Verified";
        }
        else {
                echo "Invalid Content Verification Signature";
        }
</pre>
</li>
</ul>
<p><strong style="font-size:18px;"><u>Where to use such verification?</u></strong><br />
This is an age old method for content verification which is used widely in a variety of applications. Below are a few places where hmac verification finds a place:</p>
<ul>
<li>If you have exposed an API for your vendors to submit requested data</li>
<li>If you are looking to enable third party applications in your website. Similar to developer application model of facebook.</li>
</ul>
<p>Hope you liked the post. Do leave your comments.<br />
Enjoy!</p>
<script type="text/javascript">var wordpress_toolbar_urls = ["http:\/\/php.net\/manual\/en\/function.hash-hmac.php"];var wordpress_toolbar_url = "http://abhinavsingh.com/blog/wordpress-toolbar";var wordpress_toolbar_oinw = "oinw";var wordpress_toolbar_hash = "aHR0cDovL2FiaGluYXZzaW5naC5jb20vYmxvZy8yMDA5LzEyL2hvdy10by1hZGQtY29udGVudC12ZXJpZmljYXRpb24tdXNpbmctaG1hYy1pbi1waHAvPHdwdGI%2BSG93IHRvIGFkZCBjb250ZW50IHZlcmlmaWNhdGlvbiB1c2luZyBobWFjIGluIFBIUDx3cHRiPmh0dHA6Ly9hYmhpbmF2c2luZ2guY29tL2Jsb2c8d3B0Yj5BYmhpJiMwMzk7cyBXZWJsb2c%3D";</script>]]></content:encoded>
			<wfw:commentRss>http://abhinavsingh.com/blog/2009/12/how-to-add-content-verification-using-hmac-in-php/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
	</channel>
</rss>
