New in BIG-IP version 11.1 are iFiles, a feature that allows users to load files through tmsh or the GUI onto the BIG-IP which can be referenced from iRules. This has an immediate use case of supplanting several of our codeshare entries for sorry and/or maintenance pages delivered directly from the BIG-IP instead of redirecting to a server to handle those requests. In this tech tip, I’ll cover the command options, the GUI configuration, and finally offer up a maintenance page iRule referencing iFiles.

Planning the Maintenance Page

When serving up html pages from an iRule in a variable or a data-group, several things, such as encoding images and escaping special characters to prevent Tcl errors or unfortunate interpretations, must be considered. With iFiles, however, much (and potentially all) of that trouble is eliminated. For this maintenance page, I want to return an HTML5 canvas bouncing F5 ball (original script source can be found here at vectorlight.net) to distract users during maintenance. So I’ll need two files, one image file for the F5 bouncing ball, and one text file for the html elements. The html text I’m using is below:

<html><script>
        var surface;
        var happy;
        var x = 50;
        var y = 0;
        var dirX = 1;
        var dirY = 1;

        function drawCanvas() {
            // Get our Canvas element
            surface = document.getElementById("myCanvas");
           
            if (surface.getContext) {
                // If Canvas is supported, load the image
                happy = new Image();
                happy.onload = loadingComplete;
                happy.src = "f5b_mini.png";
            }
        }

        function loadingComplete(e) {
            // When the image has loaded begin the loop
            setInterval(loop, 15);
        }

        function loop() {
            // Each loop we move the image by altering its x/y position
           
            // Grab the context
            var surfaceContext = surface.getContext('2d');
           
            // Draw the image
            surfaceContext.drawImage(happy, x, y);

            x += dirX;
            y += dirY;

            if (x <= 0 || x > 500 - 18) {
                dirX = -dirX;
            }
            if (y <= 0 || y > 250 - 28) {
                dirY = -dirY;
            }
        }
</script>

<body onload="drawCanvas();">
  <center>
    <h1>Hey there...</h1><br>
    <h2>Relax and be mesmerized by the F5 ball as we make some changes</h2><br>
    <div>
        <canvas id="myCanvas" width="500" height="250">
            <p>Your browser doesn't support canvas.</p>
        </canvas>
    </div><br>
    <h2>We'll be back online shortly...the DevCentral team</h2>
  </center>
</body></html>

Creating the iFiles

Now that my page is ready, I can upload the files. This is done in System->File Management->iFile List->Import:

iFile_import_2

iFile_import_3

A couple quick notes on importing files. First, iFiles maximum size is 4M. Second, it’s probably a good idea to adopt a naming standard early in use of iFiles. I’m using <app_function|name_type>, but whatever works, right? Now that the files are on the system (default location: /config/filestore/files_d/Common_d/ifile_d), I need to create a reference for each of them under Local Traffic->iRules->iFile List. I’m just repeating the name I used for the iFile itself:

iFile_import_4

iFile_import_5

The iFile Command Syntax

The complete syntax for the iFile command is below. For details on each command, please visit the iFile wiki page.

ifile get <iFile Name>
ifile listall
ifile attributes <iFile Name>
ifile size <iFile Name>
ifile last_updated_by <iFile Name>
ifile last_update_time <iFile Name>
ifile revision <iFile Name>
ifile checksum <iFile Name>
array set <variable> [ifile attributes <iFile Name>]

Creating the iRule

Obviously the logic to serve up the maintenance page would need to be adjusted for a production environment, but for this example I’m just doing an HTTP::respond if the URL is “/”, and then I need a condition for the image as well. So what used to be a lot more work with encoding images and massaging javascript, with iFiles, I can just return the contents with no concerns utilizing the [ifile get <iFile Name>] command. It really is that simple.

when HTTP_REQUEST {
    if { [HTTP::uri] eq "/" } {
        HTTP::respond 200 content [ifile get testapp_index_txt]
    } elseif { [HTTP::uri] eq "/f5b_mini.png" } {
        HTTP::respond 200 content [ifile get testapp_f5ball_img]
    } else { discard }
}

Browsing to the virtual results in this page:

iFile_import_7

Conclusion

I highlighted the maintenance page use case, but data served from external files will be useful for a large number of scenarios. Happy coding with the new iFiles feature delivered in BIG-IP v11.1.