JavaScript EditorFree JavaScript Editor     Perl Manuals 

Main Page

22.2. The PerlPlus Browser Plug-in

Now we'll briefly examine Frank Holtry's PerlPlus Plug-in, a loadable Netscape extension that executes Perl programs on a client computer. The Perl programs themselves can exist anywhere on the Net—the mere act of browsing a PerlPlus program (or any page with an HTML <EMBED> tag pointing to a PerlPlus program) may start it executing, subject to the result of an authentication procedure.

Netscape publishes an API for C language plug-ins that describes how to register a plug-in instance, read streaming data from a browsed URL, access system services, and so on. In 1996, Stan Melax used these specifications and developed the first plug-in for the Perl world so he could run Perl OpenGL programs in a browser. Basically, Stan's plug-in would read the browsed OpenGL program, wrap it in a Safe module, and feed the result to Perl. The Safe wrapper code provided security, and passed window information to the OpenGL code so it could properly embed itself within the browser.

In 1999, Frank rewrote the plug-in with an eye toward enhanced security. His idea was to use the Opcode module and restrict the opcodes available to the browsed Perl program. It's a multilevel scheme, from no security, in which all Perl opcodes are legal, to high security, where so many opcodes are forbidden that only the simplest Perl programs can run. Furthermore, a CGI program must first validate the browsed URL and return its opcode security level, a single digit from 0 through 5. The security CGI might be as crude as this simple table lookup:

#!/usr/local/bin/perl -w
# perlplus-secure.cgi - lookup a script's security level and inform the plugin.

use CGI qw/header param/;
use strict;

my $url_root = '';
my %urls = (
    "$url_root/clock-bezier.ppl" => 4,
    "$url_root/hw.ppl"           => 2,
    "$url_root/tkhanoi.ppl"      => 4,

my $url = lc param('URL');
my $sec_level = $urls{$url} || 0;

print header(-type => 'application/x-perlplus:.ppl:Perl'), "$sec_level\n";

Because the plug-in security model is under review, we won't examine this subject further.

As it happens, Perl/Tk programs generally have to run with most opcodes enabled, so browsing untrusted PerlPlus/Tk programs is a major security risk; imagine unleashing the full power of Perl inside your browser![65] Nevertheless, it's easy to imagine a trusted environment where you know that the served PerlPlus programs are nonlethal.

[65] Think carefully, too, before you enable Java, or install your next plug-in and let boatloads of programs of unknown quality and origin execute on your machine.

22.2.1. Embedding Perl/Tk in Other Windows

Tk Toplevels, including the MainWindow, have an optional -use argument that indicates the window ID[66] within which the Toplevel should be embedded. (Normally a Toplevel appears inside the display's root window.) Any window you know the window ID of will work, even an xclock. Try it! Use xwininfo to determine an arbitrary window ID.

[66] Use the window information command id to fetch the window ID of any Tk widget.

In our case, the PerlPlus plug-in makes Netscape's window ID available via a qualified Perl scalar, $Plugin::brinfo{xwindow_id}. Here's a bit of code that dumps the %brinfo hash key/value pairs and embeds a MainWindow within Netscape:

open PPLLOG, '>/tmp/ppl.log' or die $!;
foreach (sort keys %Plugin::brinfo) {
    print PPLLOG $_ . ' ' x (20 - length $_) . " : $Plugin::brinfo{$_}\n";
close PPLLOG;

my $mw = MainWindow->new(-use => $Plugin::brinfo{xwindow_id});

And here is what the file /tmp/ppl.log shows us:

display              : 148717568
version              : 0.95.04
x_len                : 666
x_min                : 0
xwindow_id           : 88081995
y_len                : 272
y_min                : 0

The display hash key is the X display pointer, which you might find useful when performing low-level X11 functions, perhaps via X11::Protocol. x_min and y_min are the pixel coordinates of the top-left corner of the Netscape-provided window, and x_len and y_len are the width and height of the window, respectively.

22.2.2. Embedded Versus Full-Screen Mode

Figure 22-5 depicts a full-screen Towers of Hanoi[67] simulation. A PerlPlus/Tk program runs in full-screen mode when its URL is browsed directly. In this case, your Tk program has an entire window all to itself. $Plugin::brinfo{x_len} and $Plugin::brinfo{y_len} define the window's width and height, and $Plugin::brinfo{x_min) and Plugin::brinfo{y_min) are both zero. If your MainWindow is larger than the Netscape window, it's clipped on the right and/or bottom.

[67] See Appendix C, "Complete Program Listings" for a complete tkhanoi program listing.

Figure 22-5

Figure 22-5. Full-screen Towers of Hanoi program

The other way to invoke a PerlPlus/Tk program is via an HTML <EMBED> tag:

    Countdown to 2038, <EMBED src="y2k.ppl" width=225 height=50> although
    there's not much hope I'll be around for the event!

This code produced Figure 22-6, a Perl/Tk program constrained to a 225 x 50 window.

Figure 22-6

Figure 22-6. A constrained, embedded Perl/Tk window

For an embedded Perl/Tk window, $Plugin::brinfo{x_min} and $Plugin::brinfo{y_min} are the pixels offsets from the top-left corner of the Netscape window, not necessarily zero. If your code is flexible enough, it can use the following to resize itself to the area supplied by Netscape:

my $geom = $Plugin::brinfo{x_len} . 'x' . $Plugin::brinfo{y_len};

22.2.3. How You Can Contribute to the PerlPlus Plug-in Project

The PerlPlus plug-in is available for public download and development at Head to Sourceforge; get yourself a username and password; ensure you have an environment that includes SSH, SSL, and CVS; and you're all set to web-over to the CVS repository to examine the source and get the entire source distribution or diffs of various versions, all from within your favorite browser.

If you want to work on the plug-in, contact Frank Holtry via the Sourceforge page, and he'll add you as a developer. Here's a sample CVS command to check out the source distribution:

export CVS_RSH=/path-to/ssh
cvs -z3 co 

If you're behind a firewall, you'll need an SSH wrapper such as this, or else your CVS commands will appear to hang:

exec /usr/local/bin/ssh -P $*

The -P option tells ssh to use a nonprivileged port. You'll end up with a directory named PerlPlusPlugin, a copy of the entire distribution.

JavaScript EditorJavaScript Formatter     Perl Manuals