Category Archives: Tips & Tricks

Update Google AMP Cache with Perl

While implementing Google AMP (Accelerated Mobile Pages) for your website, it might occur to you that you might need to update your page, and how would the AMP cache be invalidated/flushed/updated. Google AMP project has an easy solution for this, it’s an API call to the invalidate any URL.

We can use the update-cache request to update and remove content from the Google AMP Cache. Google AMP cache updates content based on the max-age present in the header when the page was last fetched. The update-cache endpoint requires the user to make a signed request using a self generated RSA private key, the public key should be available at a standard location on your website.

I faced the same dilemma, I had read the docs, but couldn’t find any ready-made solution in Perl, so I had to write mine, which I will be sharing with you. Here’s how to get going.

First we need to generate the the private & public keys:

$ openssl genrsa 2048 > private-key.pem
$ openssl rsa -in private-key.pem -pubout >public-key.pem
$ cp public-key.pem <document-root-of-website>/.well-known/amphtml/

replace <document-root-of-website> with your website’s document root.

Next, here’s the Perl code to which accepts an URL which needs to be invalidated. I have commented the code so its easier to understand.


use utf8;
use MIME::Base64 qw[encode_base64url];
use Mojo::UserAgent;
use Crypt::OpenSSL::RSA;
use Mojo::URL;
use Mojo::File;

## paths to keys
my $path_to_priv_key = 'private-key.pem';

my $ua = Mojo::UserAgent->new;

## get URL from command line argument
my $url = shift;

unless ( defined($url) && $url ) {
die('URL required');

my $url_obj = Mojo::URL->new($url);

## fetch the JSON containing the caches those need to be invalidated.
my $caches = $ua->get('')->res->json;

unless ( defined($caches) && ref($caches) ) {
die('Could not get caches');

## load the private key
my $priv_key = Mojo::File->new($path_to_priv_key)->slurp;
## create openssl private key instance
my $rsa_priv_key = Crypt::OpenSSL::RSA->new_private_key($priv_key);

## select the hashing algo to use, which as specified by Google AMP is SHA-256

## loop through the caches to be invalidated
foreach my $cache ( @{ $caches->{caches} } ) {
## build the URL to invalidate
my $url_to_sign = sprintf( '/update-cache/c/s/%s%s?amp_action=flush&amp_ts=%s', $url_obj->host, $url_obj->path, time() );

my $encrypted_sig = $rsa_priv_key->sign($url_to_sign);

## get AMP-style hostname,
my $host_amp_style = $url_obj->host;

$host_amp_style =~ s/([.-])/($1 eq '.')?'-':'--'/eg;

## URL-safe base64 encode the signature
my $sig = encode_base64url($encrypted_sig);

## build API URL to call
my $api_url = Mojo::URL->new( sprintf( 'https://%s.%s%s&amp_url_signature=%s', $host_amp_style, $cache->{updateCacheApiDomainSuffix}, $url_to_sign, $sig ) );

## make request
my $tx = $ua->get($api_url);

## print reponse, you may change this according to your needs
print $tx->res->body;

Further reading:

Solution for Copy Paste or right click disabled in Websites Chrome

Do you hate those pesky javascripts. Majority of the banking, utility bill payment etc so called secured websites try to limit their users by putting up limitations on their users ability to copy and paste. I totally disagree on this limitation because if you are copying from a reliable source, maybe from a vault app or even from a plain vanilla notepad, you are actually more confirmed about the data rather than typing it out yourself.

Here’s how you can avoid the limitations easily, without installing anything else in Chrome.

Read more »

Google Authenticator: Moving To A New Phone

Getting a new HTC One left me wondering how will I move Google Authenticator from my HTC Legend, I didn’t want to do everything all over. To my amazement I found Google has come up with a solution for a situation like this, it’s the “Move to a different phone” option in 2-step authentication setting page. It was a breeze switching to a new phone. Install Google Authenticator on your new phone and follow the “Move to a different phone” link.


Monitor Files & Directory For Modifications With PHP

One can monitor for changes to files & directories, including events like open, close, new file, delete, rename & all other file/directory operations.

The following code snippet should be self-explanatory:

$data_file = '/var/data/my_data_file.txt';

$inotify_fd = inotify_init();

$watch_descriptor = inotify_add_watch($inotify_fd, $data_file, IN_OPEN);

while (1)
$events = inotify_read($inotify_fd);
$filepath = $events['name'];

print "File opened";

inotify_rm_watch($inotify_fd, $watch_descriptor);


List Modified Filenames In Git

I was working on a few enhancement features of an existing project, after a few weeks work I was required to make some completed features live, so I was wondering what all files have been modified. So the Git versioning came to help, and by specifying two commit SHA1s I was able to retrive the list of files modified between the commits. Here’s how to do it,

$ git diff --name-only afd98 a3d55

Monitor Directory For New Files With WSH

Sajal wanted to monitor a directory, detect new file(s) and open them in their associated applications, I remember monitoring directory for changes in Linux in a Perl script. Doing something similar on Windows it seemed tough, but a after a little pondering I remembered about Windows Script Host (WSH), and after a bit of googling, coding, trial and errors, I came up with a script which does all that is required, it’s written in VBScript.

strDrive = "D:"
strFolder = "\\dropbox\\downloads\\"
strComputer = "."
intInterval = "5"

' Connect WMI service
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\cimv2")

' build query
strQuery =  "Select * From __InstanceCreationEvent" _
& " Within " & intInterval _
& " Where Targetinstance Isa 'CIM_DataFile'" _
& " And TargetInstance.Drive='" & strDrive & "'"_
& " And TargetInstance.Path='" & strFolder & "'"

' Execute notification query
Set colMonitoredEvents = objWMIService.ExecNotificationQuery(strQuery)

' get a shell application object
Set WshShell = WScript.CreateObject("Shell.Application")

Set objLatestEvent = colMonitoredEvents.NextEvent
' strip out the real path
Response = Split(objLatestEvent.TargetInstance.PartComponent, "=")
' remove slash & quotes
FileName = Replace(Response(1), """", "")
FileName = Replace(FileName, "\\", "\")
' open the file in it's associated program
WshShell.ShellExecute FileName, "", "", "open", 1
Wscript.Echo FileName

Skydrive currently offering 25GB free space

Microsoft’s SkyDrive is offering 25GB of free cloud storage upgrade currently to its loyal user base.

Read on how to get it for free

Force Download Specific Files with Apache & Htaccess

At time we want visitors to download instead of viewing the file instead of viewing inside their browser. As a visitor I have faced problems with PDF files at many sites where I wanted to download the PDF file and view it separately because viewing the PDF inside the browser slows down the browser and sometimes causes the browser to crash.

So, If you want to force people to download a file or all files in a specific directory and so on, if is very easy to do so with the help an Apache directive which sets the response header ‘Content-Disposition’ to ‘attachment’, see the examples below:

<Files *.pdf>
Header set Content-Disposition attachment

<Directory /var/www/html/images>
Header set Content-Disposition attachment

Play Snake on any youtube video

How many times have you sat in front of your monitor just the video to start.. hoping for a faster start of the video. You don’t have to be bored while waiting for that cool youtube video you are about to watch.

Read more »

Copy text, url from firefox to android/iphone

You must already have scanned bar codes to download apps, browse urls from your desktop to your mobile, isn’t it very convenient, requires no typing and no extra app installation for copy pasting, everything happens via the bar-code image. Read more »

search engine optimization