📄 ch15.htm
字号:
platform-independence when serving bytecode. Again, as previously mentioned, this
isn't really an issue when executing Perl code, because there are operations that
may reduce to bytecode on one architecture but still won't execute on another architecture.
This is a win with the Java language, however, because most or all of its operations
are guaranteed to run under any architecture.
<P>
<LI>Browser Communications: It's certainly nice to be able to communicate back to
the browser the result of running a given program. It's arguable, on the other hand,
how much the client really wants to know. Java provides the programmer with the capability
to create and manipulate windows or drawing areas (rectangles) within the browser
window. These features are commonly used to do animation and other dynamic processes
within the browser, often for entertainment's sake. This also gives the browser the
capability to execute code and produce output, such as summing the values from a
form or figuring the tax on a purchase, which might otherwise require a CGI routine
on the server. Perl, as a language, provides extremely powerful capabilities for
processing data and manipulating text, but it is still a little weak on the animation/windowing
side of things. Of course, you can use external modules and libraries, which do handle
this in a much nicer way, to communicate with the browser. We'll look at an example
a bit later, using the OpenGL module. You could also use the Java interface for communicating
with the browser/client and use Perl for processing the data. In the simple case,
and possibly the most utilitarian, all the client may need to know is whether the
script ran successfully, or possibly the results, if the script is manipulating some
local files, for instance.
</UL>
<P>So, now that we've considered what could and should be a part of a Perl plug-in,
let's take a look at the one that has already been developed.</P>
<P>The Netscape plug-in development kit provides the developer with a simple interface
to and from the Netscape browser. The plug-in developer defines the MIME type/extension
that he or she wants Netscape to associate with the plug-in, and whenever any URL
of this type is received, the plug-in is invoked and is passed the content of the
URL. It's then up to the plug-in to process the content as it sees fit and exit with
an appropriate value that is returned to Netscape.</P>
<P>The existing Perl plug-in is quite simple in its implementation, but it has an
enhanced entertainment value and visual appeal because it's implemented using the
OpenGL 3D Graphics Rendering kit. It can communicate with the browser directly, creating
windows within the browser for its output.</P>
<P>The OpenGL plug-in source is distributed with the OpenGL Perl5 extension, available
from the CPAN in the <TT>~modules/by-module/OpenGl</TT> directory. If you don't have
OpenGL, you can obtain a library, called MesaGL, which emulates most of OpenGL's
features and capabilities for free. MesaGL is available by anonymous ftp from<TT>
ftp://iris.ssec.wisc.edu/pub/Mesa</TT>.</P>
<P>You'll need to install the OpenGL or MesaGL C library and have the OpenGL Perl5
extension, as well as the Safe/Opcode module available, for the plug-in to work.</P>
<P>Once you've installed everything, you can try some of the sample scripts that
come with OpenGL. In particular, the OpenGL Perl plug-in is distributed with a sample
Perl script called quest.glp, which, when run by itself, produces a window with a
simple animated 3D maze, which looks something like Figure 15.1.</P>
<P><A HREF="17wpp01.jpg" tppabs="http://210.32.137.15/ebook/Web%20Programming%20with%20Perl%205/17wpp01.jpg"><B>Figure 15.1.</B></A> The Maze object.</P>
<P>While the script is running, the Maze object you see will actually be rotating
on its 3D axis and slowly moving closer to, then farther away from, the foreground.
It's not particularly useful, granted, but it is visually appealing. Now, let's take
a closer look at the source code for the plug-in to see how it works its simple magic.</P>
<P>As with any Netscape plug-in, there are C code routines that you must code up
to make it do what you want. As we've previously mentioned, the plug-in must be able
to tell Netscape what MIME type it's able to handle. This is done through the <TT>NPP_GetMIMEDescription()</TT>
function in the npshell.c source code file. This particular plug-in sets itself up
to handle URLs of the</P>
<PRE><FONT COLOR="#0066FF">application/Perl-opengl:.glp
</FONT></PRE>
<P>type. Whenever a URL with the extension .glp is received by Netscape, it will
invoke the plug-in and pass in the contents. Once the plug-in is invoked, the <TT>NPP_Write()</TT>
function is eventually called, and here is where the plug-in developer chooses to
actually invoke Perl, using the UNIX <TT>popen(3S)</TT> routine. Once Perl is started
and waiting at the other end of the pipe for input, the contents of the URL (the
Perl script) is fed to it, using the <TT>Safe::reval()</TT> method discussed in Chapter
3. This also implies that a Safe Compartment is created, and the exported symbols
from the <TT>OpenGL</TT> module are <TT>permit()</TT>'d into it. We end up with a
Netscape window that looks like Figure 15.2.</P>
<P>The html that invokes the plug-in has the <TT>EMBED</TT> tag</P>
<PRE><FONT COLOR="#0066FF"><EMBED src="quest.glp", width=300, height=300>
</FONT></PRE>
<P>which causes the plug-in to be invoked with the right extension.</P>
<P>Hopefully, as time allows, we'll start to see other useful Netscape plug-ins that
embed Perl and implement an encryption method for the exchange of scripts and bytecodes.
<H3 ALIGN="CENTER"><A NAME="Heading6"></A><FONT COLOR="#000077">Executing Perl as
a Helper Application</FONT></H3>
<P>The other way to execute Perl scripts from the Net on your client is via the use
of a MIME type, mapping to a helper application. Under UNIX you need to coordinate
the tow files, .mime.types, and .mailcap in order to correctly map the URL's type
to the Perl application.</P>
<P>Now the easiest, and the most dangerous, way to implement this is with the simple
entry in your .mailcap:</P>
<PRE><FONT COLOR="#0066FF">application/Perl; /usr/local/bin/Perl %s
</FONT></PRE>
<P>And in your .mime.types:</P>
<PRE><FONT COLOR="#0066FF">type=application/Perl\
desc="Ordinary Perl script" \
exts="myplt"
</FONT></PRE>
<P><A HREF="17wpp02.jpg" tppabs="http://210.32.137.15/ebook/Web%20Programming%20with%20Perl%205/17wpp02.jpg"><TT><B>Figure 15.2.</B></TT></A><TT> </TT>The
perl-opengl plugin page. <BR>
<BR>
These will map any URL with the .myplt extension to be executed automatically with
Perl. Now that we've told you how to do it, we emphasize that you should never, ever
do this, under any circumstances. Even using the special extension, .myplt, if anyone
ever learns that you've set this up, they might be able to send you a script that
could compromise your security in the guise of an innocuous-looking URL. Fortunately,
Netscape nowadays has the built-in warning dialog, which prompts you before actually
executing the script.</P>
<P>In any case, it's much better to use the Safe extension to set up a secure environment
first, then execute the script within this environment. Listing 15.1 shows a simple
script called HelperAppPerl that you can install and then set up your .mime.types
and .mailcap files to invoke it with the Perl script you've downloaded.
<H3 ALIGN="CENTER"><A NAME="Heading7"></A><FONT COLOR="#000077">Listing 15.1. HelperAppPerl.</FONT></H3>
<PRE><FONT COLOR="#0066FF">#!/usr/local/bin/Perl
require Safe;
my $cpt; # Safe compartment object
my $error; # holds errors from reval()'in the URL
my $privfile = "$ENV{HOME}/.helper.privs";
my ($share, @permitted);
my $program;
$cpt = new Safe;
# Sanity check: confirm that this version of Perl really is op_mask aware.
# Thanks to Malcolm Beattie for some of these bits, from SafeCGIPerl
$cpt->reval(`open();');
if ("$@" !~ /open trapped by operation mask/) {
die(<<`EOT');
Your version of Perl is not op_mask aware. See the file README
that comes with the distribution of the Safe extension to Perl.
EOT
}
# Open and parse the optional .helper.privs file
if( -e $privfile){
open(PRIVS, "<".$privfile) or
die "Can\'t open your privfile, $privfile\n";
while(<PRIVS>){
next if /^\s*\#/; # skip comments
($share = $_) =~ s/^([^#]*).*/$1/; # skip comments on same line
warn "Permitting ops: $share\n" if ($debug);
@permitted = split(` `,$share);
$cpt->permit( @permitted );
}
}
# Now we're ready to go
$program = $ARGV[0];
(-r "$program") or (die "program $program not found\n");
# Share STDIN and STDOUT but no other filehandles.
# Share %ENV so that the script can see our environment variables.
# Share $" so that they can interpolate arrays in double-quotish contexts.
#
$cpt->share(qw($" *STDIN *STDOUT %ENV ));
$error = $cpt->rdo($program);
if ($@) {
die "Program error: $@";
}
</FONT></PRE>
<P>Once you've set up your .mime.types file like this</P>
<PRE><FONT COLOR="#0066FF">type=application/Perl\
desc="Safe Perl script" \
exts="mypl"
</FONT></PRE>
<P>and your .mailcap file like this</P>
<PRE><FONT COLOR="#0066FF">application/Perl; /usr/local/bin/HelperAppPerl %s
</FONT></PRE>
<P>then any URL with the extension .mypl will invoke this helper application, which
will compile and run the script within the Safe compartment.</P>
<P>In the HelperAppPerl script, we perform the following tasks:
<OL>
<LI>Create a new Safe object (compartment) using <TT>$cpt</TT>.
<P>
<LI>Perform a sanity check on the safe compartment to be sure we're using a Perl
that has the Safe masking capability. (This technique is derived from <TT>SafeCGIPerl</TT>,
discussed in Chapter 3.)
<P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -