Tag Archives: https

Pixenate, Virtual Directories and Secure websites.

I’ve spent some time recently troubleshooting an issue a customer was having with Pixenate. The problem hadn’t arisen before, but thinking about it, it’s a problem which might arise in the future so I think it’s worth blogging about and documenting in the official documentation.

The customer was using Microsoft’s IIS web server and had setup a virtual directory for all photographic images – a perfectly reasonable and sensible setup. The photos resided on an entirely different machine and used IIS’s virtual directory feature to map from a URL to the remote machine. Everything seemed to work fine until they switched over to their production machine which was using HTTPS instead of HTTP. The images would load OK but when users tried to change the photos, Pixenate would complain with an error. The problem was due to a combination of using HTTPS and Virtual directories. Fortunately there is a workaround. A long time ago I added a facility to Pixenate to allow customers to implement their own custom image-loading (say for loading images from BLOBs stored in a database for example) . It wasn’t until recently that it found a use…

Pixenate’s default behavior assumes that there is a simple mapping of URL to file-system path. E.g. If the IIS DocumentRoot is at

C:\InetPub\wwwroot

…and if an image can be accessed via the following url…

… then the file resides on the file system at C:\InetPub\wwwroot\images\abc.jpg , and Pixenate can be initialized by calling…

PXN8.initialize(“/images/abc.jpg”);

…or…

PXN8.initialize( { url: “/images/abc.jpg” } );

…or even…

PXN8.initialize( { url: “/images/abc.jpg” , filepath: “../images/abc.jpg” } );

(this last example assumes pixenate has been installed at C:\InetPub\wwwroot\pixenate – see PXN8.initialize() in the API reference.)

Why would you want to use the last example? Well imagine your photos are served from a secure site ( one which uses https instead of http ). In this scenario, the most common PXN8.initialize(“/images/abc.jpg”); will still work because Pixenate will try to load the C:\InetPub\wwwroot\images\abc.jpg file if it exists.

If a Virtual directory was in use so that /images/ actually pointed to D:\images , Pixenate would no longer work because having tried and failed to read C:\InetPub\wwwroot\images\abc.jpg it would then try to retrieve https://localhost/images/abc.jpg using Perl’s LWP::Simple ( libwww-perl library ) and fail.

In this scenario, Pixenate must be given a back-stage pass so it can bypass https. Just how do you do this? Well the documented ‘filepath’ property won’t work because the image resides in a virtual directory which isn’t accessible from the pixenate directory (in this example, the virtual directory maps to a different disk but it could just as easily map to an entirely different computer).

The standard methods of loading Images in Pixenate (either from the filesystem on which pixenate resides or via LWP::Simple) won’t suffice if HTTPS and virtual directories are in use. This calls for some custom image loading code. Fortunately it’s possible in Pixenate to specify your own custom image loader and use that instead.

In this scenario, the Pixenate server needs to load images from the D:\images directory, and to do this you need to provide a server-side plugin…

use strict;
use Sxoop::PXN8 ':all';
#
#
# insert the following new property/line to your pixenate/config.ini file...
#
# VIRTUAL_IMAGE_ROOT = "D:/images/" ,
#
#
sub fetch_from_vpath
{
	 my ($image, $params) = @_;

	 unless (exists $ENV{PIXENATE_VIRTUAL_IMAGE_ROOT} )
	 {
		  die "The VIRTUAL_IMAGE_ROOT configuration property has not been set!\n";
	 }

	 my $path = $ENV{PIXENATE_VIRTUAL_IMAGE_ROOT} . $params->{virtual_path};

	 unless (-e $path){
		  die "File $path does not exist\n";
	 }
	 my $imrc = $image->Read($path);

	 if (is_imagick_error($imrc)){
		  die "ImageMagick cannot open file: $imrc\n";
	 }
	 return $image;
}
AddOperation('vpath', \&fetch_from_vpath);
1;

Save the code above to a filename ending in .pm and copy it to the pixenate/lib/Sxoop/PXN8/plugins directory.
To use the plugin when starting pixenate use the following javascript code …

PXN8.initialize( { url: "/images/abc.jpg" , // for the web client
                   source: "vpath",          // specifies which plugin should be used for loading
                   virtual_path: "abc.jpg"  // the path used by the plugin
                  } );


This will enable you to use Pixenate on a secure server with virtual directories set up for images.
There are many possible ways of storing photos, filesystem (local or remote), database, cloud (S3) but I’m confident Pixenate is flexible enough to cope with whatever exotic permutations of the above can be thrown at it.

Tagged , , , ,